Creating a customized objects function (in R) that uses regular expression - regex

Why does not the following custom objects function work?
objects0 <- function(find_term)
{
objects(pattern=glob2rx(paste0("*",find_term,"*")))
}
txt1 <- 100
tt <- 200
> objects0('txt')
character(0)
But when I write
objects(pattern=glob2rx(paste0("*",'txt',"*")))
it works just fine.

You need to specify the environment where to look for objects.
Add parameter envir=parent.frame() to objects call:
objects0 <- function(find_term)objects(pattern=glob2rx(paste0("*",find_term,"*")), envir=parent.frame())
Maybe a better way is to add envir=globalenv() to ensure that the search is done in the global environment always.

Related

Use map inside map?

I have two lists: One with some tidy data and another with models made with tidymodels package
data_list <- list(train,test)
model_fits <- list(tree,forest,xgb)
I want to make a new list with a confusion matrix for train and test for every model.
The function that calculates confusion matrix:
ConfMat <-
function(df,data){
df <-
predict(df,new_data = data, type = "class") %>%
mutate(truth = data$NetInc) %>%
conf_mat(truth,.pred_class)}
I have tried to do this (x,y is arbitrary).:
map(data_list,map(model_fits,ConfMat(x,y)))
My problem is that I have no idea how to actually set "x" and "y" right.
PS: double for loop works. I'm asking specifically for map solution or equivalent.
Appreciate all help i can get! cheers
Use an anonymous function -
library(purrr)
result <- map(data_list,function(x) map(model_fits,function(y) ConfMat(x,y)))
result

Scoping between output functions

I have been through (hopefully thoroughly enough) the shiny help article on scoping, and have also seen the answer regarding setting a global object here. Neither addresses, however, what I think (emphasis on "think") I need to do. If a variable is only created in an output function, can it be seen in another? Using action buttons, I'm trying to control lengthy calculations and some will only happen on condition of other things happening. As a minimal example,
library(shiny)
library(stringr)
fruitref <- c("apple","peach","pear","plum","banana","kiwi")
textareaInput <- function(inputID, label, value="", rows=10, columns=30) {
HTML(paste0('<div class="form-group shiny-input-container">
<label for="', inputID, '">', label,'</label>
<textarea id="', inputID, '" rows="', rows,'" cols="',
columns,'">', value, '</textarea></div>'))
}
ui <- fluidPage(titlePanel("minimal example"),
sidebarLayout(
sidebarPanel(
textareaInput("inputfruit", "Enter some fruits:"),
actionButton("checkfruit", "Check fruits"),
verbatimTextOutput("fruitstat")
),
mainPanel(
textOutput("fruits")
)
)
)
server <- function(input,output){
flag <- F
inputs <- eventReactive(input$checkfruit,{input$inputfruit})
continue <- reactive(flag)
output$fruitstat <- renderText({
inputs <- inputs()
inputs <- str_trim(unlist(strsplit(inputs,split="\n")),side="both")
if(length(setdiff(inputs,fruitref)) != 0 | length(inputs) == 0){
flag <- F
paste(paste(setdiff(inputs,fruitref), collapse=", "),"not in table.")
} else {
flag <- T
"All fruits ok."
}
})
output$fruits <- renderText({
paste("Continue? ",continue())
})
}
shinyApp(ui = ui, server = server)
There's a reference table and user input is checked against that table. User enters list in pieces until hitting the check button, then gets feedback whether all are OK, or if there's a mismatch. Only if all are okay do I want to continue. I tried setting a "continue" flag in the output function, but that didn't work, and setting it in the server outside of the output function would not update the value. I also tried creating an environment in the server function and using assign, but that too did not update the value when I tried to retrieve it for renderText later. Since it's not an input, accessible through input$, I figured I cannot use any of the update* functions.
This may not be the best way to set this kind of conditional. I saw in the tutorial the conditional pane, but that depends on an input, rather than something created in the function. More generally, there are more complicated objects to be created in the output functions (there will be four large tables and a plot at most; all or some subset will actually be output) that then other output functions should see, I did not think I could define them as reactive global objects, because until some later things happen, they can't be calculated.
Define continue as an eventReactive:
continue <- eventReactive(input$checkfruit, flag)
And also use the global assignment operator inside function
flag <<- F
flag <<- T
Then it will work. Tested.

how to change the name of a variable to be called using string manipulation in R?

I am trying to change the name of a variable to be called in r on the fly.
For example, dataframe trades_long_final has many columns "prob_choice1" and "prob_choice2", ... "prob_choiceN" and "col1", "col2", ... "colN".
I want to change the value of each on the fly.
For example,
trades_long_final$"prob_choice1"[1] = 10 and
trades_long_final$"prob_choice2"[1] = 10
works
but not
trades_long_final$gsub("1","2","prob_choice1")[1] = 10
as a way to call trades_long_final$"prob_choice2"[1] by substituting the 1 in prob_choice1 with a 2 because I get the error
Error: attempt to apply non-function
I need this to work because I need to loop over the columns using something like trades_long_final$gsub("i","2","prob_choicei")[1] in a loop for all i.
Thank you so much for your help. It must be a command I don't know how to use...
Instead of using $, you can use [ to change the variable name and assign the value in one line.
trades_long_final[,gsub("1","2","prob_choice1")][1] <- 10
But, it is not clear why you need to do this. Simply
trades_long_final[1, "prob_choice2"] <- 10
would be easier. From the description, "prob_choice2" is already a column in the dataset. So, it is confusing.
data
set.seed(24)
trades_long_final <- data.frame(prob_choice1 =runif(10),
prob_choice2=rnorm(10), col1=rnorm(10,10), col2=rnorm(10,30))
as akrun said, the way to do it was to use [ so that the way I did it was:
for (k in 1:numtrades){
trades_long_final[[paste("prob_choice", k, sep="")]] =
{some complex procedure...}
}

Parameterize pattern match as function argument in R

I've a directory with csv files, about 12k in number, with the naming format being
YYYY-MM-DD<TICK>.csv
. The <TICK> refers to ticker of a stock, e.g. MSFT, GS, QQQ etc. There are total 500 tickers, of various length.
My aim is to merge all the csv for a particular tick and save as a zoo object in individual RData file in a separate directory.
To automate this I've managed to do the csv manipulation, setup as a function which gets a ticker as input, does all the data modification. But I'm stuck in making the file listing stage, passing the pattern to match the ticker being processed. I'm unable to make the pattern to be matched dependent on the ticker.
Below is the function i've tried to make work, doesn't work:
csvlist2zoo <- function(symbol){
csvlist=list.files(path = "D:/dataset/",pattern=paste("'.*?",symbol,".csv'",sep=""),full.names=T)
}
This works, but can't make it work in function
csvlist2zoo <- function(symbol){
csvlist=list.files(path = "D:/dataset/",pattern='.*?"ibm.csv',sep=""),full.names=T)
}
Searched in SO, there are similar questions, not exactly meeting my requirement. But if I missed something please point out in the right direction. Still fighting with regex.
OS: Win8 64bit, R version-3.1.0 (if needed)
Try:
csvlist2zoo <- function(symbol){
list.files(pattern=paste0('\\d{4}-\\d{2}-\\d{2}',symbol, ".csv"))
}
csvlist2zoo("QQQ")
#[1] "2002-12-19QQQ.csv" "2008-01-25QQQ.csv"
csvlist2zoo("GS")
#[1] "2005-05-18GS.csv"
I created some files in the working directory (linux)
v1 <- c("2001-05-17MSFT.csv", "2005-05-18GS.csv", "2002-12-19QQQ.csv", "2008-01-25QQQ.csv")
lapply(v1, function(x) write.csv(1:3, file=x))
Update
Using paste
csvlist2zoo <- function(symbol){
list.files(pattern=paste('\\d{4}-\\d{2}-\\d{2}',symbol, ".csv", sep=""))
}
csvlist2zoo("QQQ")
#[1] "2002-12-19QQQ.csv" "2008-01-25QQQ.csv"

Assign names to variable using regular expression in R

So I have a bunch of variables in my workspace. I want to assign a subset of them to a new variable, so I can easily run functions on this subset:
workspace:
...
group10
group40
location40
test
desired assignment:
groupList <- list(group10,group40, ...)
intended regular expression:
^group[0-9]+
Any ideas?
ls accepts a pattern argument:
group10 <- group40 <- location40 <- test <- NA
mysub <- ls(pattern="^group[0-9]+")
mysub
#[1] "group10" "group40"
You can use lapply to loop over the list of variable names and get their values
groupList <- lapply(mysub, get)
or, in one line
groupList <- lapply(ls(pattern="^group[0-9]+"), get)