using paste0 in file name in exams2moodle - paste

I am trying to create a loop to automatize exams generation using the examspackage....
I have created a series of exercices like this
gr1 <- c("ae1_IntroEst_1.Rmd","ae1_IntroEst_2.Rmd","ae1_IntroEst_3.Rmd","ae1_IntroEst_4.Rmd")
gr2 <- c("ae1_IntroProcEst_1.Rmd","ae1_IntroProcEst_2.Rmd","ae1_IntroProcEst_3.Rmd","ae1_IntroProcEst_4.Rmd")
...etc...
Now, I am creating a loop to export all the exercices to moodle xml:
for (i in 1:2){
grupo <- paste0("gr",i)
exams2moodle(grupo, name = paste0("mt1_",i, "_M"), dir = "nops_moodle", encoding = "UTF-8", schoice = list(answernumbering = "none", eval = ee))
}
But I am getting this error:
Error in xexams(file, n = n, nsamp = nsamp, driver = list(sweave = list(quiet = quiet, : The following files cannot be found: gr11.
If I replace "grupo" by "gr1" then it works... (but I am generating 20 exercices). I can't figure it out...
Any ideas?
Thanks!

Because grupo is a string: "gr1". The exams2moodle's first parameter is a string (in your case) and not the list of files (as you want).
If you want use a variable which name is in a string variable, you should use get (get: Return the Value of a Named Object)
Check the sample code:
> x <- 'foo'
> foo <- 'bar'
> x
[1] "foo"
> get(x)
[1] "bar"
>
In your case:
for (i in 1:2){
grupo <- paste0("gr",i)
exams2moodle(get(grupo), name = paste0("mt1_",i, "_M"), dir = "nops_moodle", encoding = "UTF-8", schoice = list(answernumbering = "none", eval = ee))
}

Related

I'm trying to create and pass a new record which contains a map from the jython processor in streamsets but getting this error?

I want the newRecord to containt a map of column names and column values. I am getting the following error which I am not able to resolve -
Record1-Error Record1 SCRIPTING_04 - Script sent record to error: write(): 1st arg can't be coerced to com.streamsets.pipeline.stage.util.scripting.ScriptRecord : (View Stack Trace... )
from datetime import datetime
metadata_dict = {}
for metadata in sdc.records[0].value['XMLData']['Metadata'][0]['FieldDefinitions'][0]['FieldDefinition']:
metadata_dict [metadata['attr|id']] = metadata ['attr|alias']
for record in sdc.records:
try:
for row in record.value['XMLData']['Record']:
newRecord = sdc.createRecord(str(datetime.now()))
newRecord = sdc.createMap (False)
value = row ['Field']
for values in value:
column_id = values ['attr|id']
column_name = metadata_dict [column_id]
for a in values:
if a == 'value':
column_value = values ['value']
elif a == 'ListValues':
column_value = values ['ListValues']
elif a == 'Groups':
column_value = values ['Groups']
elif a == 'Users':
column_value = values ['Users']
newRecord[column_name] = column_value
sdc.output.write(newRecord)
except Exception as e:
sdc.error.write(record, str(e))
You have a bug in your code:
newRecord = sdc.createMap (False)
Here, you create a map and place it into a newRecord variable.
sdc.output.write(newRecord)
Here, you're trying to write a map, not a record, into the output.
You should do something like:
newRecord = sdc.createRecord(...
myMap = sdc.createMap(...)
myMap['foo'] = 'bar'
newRecord.value = myMap

Getting a set of a list from a list of strings

I have this dataframe:
df = pd.DataFrame({"c1":["[\"text\",\"text2\"]","[\"bla\",\"bla\",\"bla\"]"]})
and I'm removind [] and "" :
df["c2"] = df["c1"].apply(lambda x:re.sub('[\["\]]', "", x))
then I want to add df['c2'] to a list:
list = df['c2'].to_list()
Then I get this: ['text,text2', 'bla,bla,bla']
So far so good. But then I want a list with only unique values, what I could to using set(list).
The proble is that Instead of ['text,text2', 'bla,bla,bla'] I needed to get ['text','text2', 'bla','bla','bla'] so when I apply `set(list) I would get what I am expecting:
['text','text2','bla']
First, don't use list as a variable. Second, once you get ['text,text2',...] you can use str.split. So your set would be
{y for x in df['c2'].str.split(',') for y in x}
Output:
{'bla', 'text', 'text2'}
Note: You can use regex directly to extract all patterns between the \":
set(df['c1'].str.extractall('\"([^"]+)\"')[0])
Try this:
new = []
for l in list:
new.extend(l.split(',') )
new = list(set(new))
which results in new to be
['text2', 'text', 'bla']

Change a dynamic variable name with rxSetVarInfo

Trying to change a variable name of an XDF with rxSetVarInfo.
I want to merge several data sets with common var names. (I know rxMerge can/will append to filenames where needed. I want to have more control than that.)
This works:
outLetter<- "A"
exp <- list(pct.A = list(newName = paste0("X.pct.",outLetter)))
rxSetVarInfo(varInfo = exp, data = tempXDFFile)
That's where I know the original column name, pct.A. What if that's dynamic? What if this is in a function that gets called several times with different outLetter's. (The "A" isn't hardcoded.)
This does not work:
function(outLetter){
exp <- list(paste0("pct.",outLetter) = list(newName = paste0("X.pct.",outLetter)))
rxSetVarInfo(varInfo = exp, data = tempXDFFile)
}
Nor does:
exp <- parse(text = exp)
rxSetVarInfo(varInfo = exp, data = tempXDFFile)
Yes, I can hardcode all the permutations. Trying to find a more elegant approach.
Please try this code:
dynamicName <- function(outLetter){
exp <- vector(mode="list", length=1)
names(exp) <- paste0("pct.",outLetter)
exp[[paste0("pct.",outLetter)]] = list(newName = paste0("X.pct.",outLetter))
rxSetVarInfo(varInfo = exp, data = tempXDFFile)
}
Before the call to rxSetVarInfo(), "exp" contains:
$pct.A
$pct.A$newName
[1] "X.pct.A"
Running your "this works" case, I see:
> outLetter<- "A"
> exp <- list(pct.A = list(newName = paste0("X.pct.",outLetter)))
>
> exp
$pct.A
$pct.A$newName
[1] "X.pct.A"
Hope this helps!
Note, please make sure that your dynamic naming function has access to the variable "tempXDFFile", you may want to consider passing it as a parameter, like:
dynamicName <- function(outLetter, data){
exp <- vector(mode="list", length=1)
names(exp) <- paste0("pct.",outLetter)
exp[[paste0("pct.",outLetter)]] = list(newName = paste0("X.pct.",outLetter))
rxSetVarInfo(varInfo = exp, data = data)
}

D3 Table Filter in R Shiny update SQL server

I am working on a project to update a SQL database with a Shiny app using D3 Table Filter.
I am able to query the server with different text inputs and the table will render with only those rows. The next step is to edit the table in the shiny app, and have that send a query back to the server to update it.
I have enabled editing in specific columns. How could I make an edit and have it send a query?
Thank you very much in advance.
Here is my code so far:
#install.packages("devtools")
#devtools::install_github("ThomasSiegmund/D3TableFilter")
library(shiny)
library(htmlwidgets)
library(D3TableFilter)
library(RSQLite)
library(RODBCext)
library(sqldf)
dbhandle = odbcDriverConnect(connection = "driver={SQL Server};server= ... ;database= ... ;trusted_connection=true")
fulldata = sqlExecute(dbhandle, "SELECT * FROM ...", fetch = TRUE, stringsAsFactors = FALSE)
ui <- fluidPage(
# Application title
titlePanel("Patient Search"),
sidebarLayout(
sidebarPanel(
textInput(inputId = "Id", label = "Search by Account Number, Date of Birth (YYYY-MM-DD) or Last Name"),
textInput(inputId = "NextAppt", label = "Search by Next Appointment (YYYY-MM-DD)"),
submitButton(text = "Go!")
),
mainPanel(
title = 'Patient Search with D3 Table Filter in Shiny',
fluidRow(
column(width = 12, d3tfOutput('data'))
)
)
)
)
# server.R
# --------------------------------------------------------
server <- shinyServer(function(input, output, session) {
#this reactive will return the row numbers that will need to be returned in our table.
#this could depend on any of our inputs: last name, DoB, account number, or next appointment
search.criteria <- reactive({
out <- c()
outAppt <- c()
if(grepl("\\d{4}\\-\\d{2}\\-\\d{2}", input$Id)==TRUE){
out <- which(fulldata$PatientDOB==input$Id)
print(out)
} else if(grepl("\\d{5}", input$Id)==TRUE){
out <- which(fulldata$AccountNo==input$Id)
} else{
out <- which(fulldata$PatientLastName==toupper(input$Id))
}
# filter for appointment
if(grepl("\\d{4}\\-\\d{2}\\-\\d{2}", input$NextAppt)==TRUE){
outAppt <- which(fulldata$NextAppt==input$NextAppt)
if(length(out)){
out <- intersect(out, outAppt)
}else{
out <- outAppt
}
}
out
})
#make the output table
output$data <- renderD3tf({
# Define table properties
tableProps <- list(
btn_reset = TRUE,
# alphabetic sorting for the row names column, numeric for all other columns
col_types = c("string", rep("number", ncol(fulldata)))
);
d3tf(fulldata[search.criteria(),],
tableProps = tableProps,
extensions = list(
list(name = "sort")
),
showRowNames = TRUE,
tableStyle = "table table-bordered",
#this optional argument enables editing on these specific columns
edit = c("col_49", "col_50", "col_51", "col_52", "col_53"));
})
#NEED TO ADD SOMETHING HERE TO SEND QUERY TO SERVER WHEN USER EDITS
})
runApp(list(ui=ui,server=server))
I used rhandsontable. It works better as you can convert the output using hot_to_r. But because of it's simple excel like formatting, it's difficult to render images like DT
If only data, go ahead and use rhandsontable.
Eg.
rhandsontable(df) %>%
hot_cols(colWidths = c(80,150,80,80,80,80,200,200,80,80,300,80,80), manualColumnResize = TRUE) %>%
hot_col(2:13, renderer = "html") %>%
hot_col(2:13, renderer = htmlwidgets::JS("safeHtmlRenderer")) %>%
hot_col(1, renderer = "
function(instance, td, row, col, prop, value, cellProperties) {
var escaped = Handsontable.helper.stringify(value),
img;
if (escaped.indexOf('http') === 0) {
img = document.createElement('IMG');
img.src = value;
Handsontable.dom.addEvent(img, 'mousedown', function (e){
e.preventDefault(); // prevent selection quirk
});
Handsontable.dom.empty(td);
td.appendChild(img);
}
else {
// render as text
Handsontable.renderers.TextRenderer.apply(this, arguments);
}
return td;
}")
})
observeEvent(input$submitComments, {
a = hot_to_r(input$upcomingAuctionsTable)
# sqlSave(myConnUpcom, a, tablename = "test", rownames = FALSE, varTypes = c(date = "varchar(255)"))
sqlUpdate(myConnUpcom, a, tablename = "temp", index = "item_id")
})

Replace existng column in MSR

Why does the following MSR code not replace the original column "Var1"?
rxDataStep(inData = input_xdf, outFile = input_xdf, overwrite = TRUE,
transforms = list(Var1 = as.numeric(Var1)),
transformVars = c("Var1")
)
At the moment, RevoScaleR doesn't support changing the type of a variable in an xdf file (even if you write to a different file). The way to do it is to create a new variable, drop the old, and then rename the new variable to the old name.
I would suggest doing this with a transformFunc (see ?rxTransform for more information), so that you can create the new variable and drop the old, all in one step:
rxDataStep(inXdf, outXdf, transformFunc=function(varlst) {
varlst$Var1b <- as.numeric(varlst$Var1)
varlst$Var1 <- NULL
varlst
}, transformVars="Var1")
# this is fast as it only modifies the xdf metadata, not the data itself
names(outXdf)[names(outXdf) == "Var1b"] <- "Var1"
MSR doesn't allow you to overwrite a variable in place with a different variable type.
You have two options: Write to a different variable or write to a different file. I have added a bit of code that shows that both solutions work as stated in MRS 9.0.1. As stated in the comments, there is some point in earlier versions where this might not work. I am not totally sure where that point is, so the code should let you know.
input_xdf <- "test.xdf"
modified_xdf <- "test_out.xdf"
xdf_data <- data.frame(Var1 = as.character(1:10),
Var2 = 2:11,
stringsAsFactors = FALSE)
rxDataStep(inData = xdf_data,
outFile = input_xdf,
rowsPerRead = 5,
overwrite = TRUE)
rxDataStep(inData = input_xdf,
outFile = input_xdf,
overwrite = TRUE,
transforms = list(Var1b = as.numeric(Var1)),
transformVars = c("Var1")
)
rxGetInfo(input_xdf, getVarInfo = TRUE, numRows = 5)
rxDataStep(inData = input_xdf,
outFile = modified_xdf,
transforms = list(Var1 = as.numeric(Var1)),
transformVars = c("Var1")
)
rxGetInfo(modified_xdf, getVarInfo = TRUE, numRows = 5)