How to use function with variable in R? - r

in R,the pdf function can save graph in c:/test:
pdf("c:/test")
I want to make a variable substitue pdf ,how can i make it run ?
str<-"pdf"
str("c:/test")

get() does this:
get(str)("c:/test")

s = "pdf" ; do.call(s, list("c:/test"))
or in two steps,
cl <- call(s, "c:/test")
eval(cl)

You can extract the function specified by the name in str with match.fun:
match.fun(str)("c:/test")
By the way: It is not a good idea to name an object str since this is the name of a basic function in R.

Related

Converting the argument name of a function into string

I have developed a function which will take a list of files and will do some statistical tests and will generate a excel file. In the last line of function (return object) I want the function will return a excel file with same names as input file names. In my example it will give list_file.xlsx. IF I enter another file let's say tslist_file it should automatically return tslist_file.xlsx. The function is properly working. Suggest me how I code last line of the function so that I can generalise it.
newey<-function(list_files){
tsmom<-do.call(cbind,lapply(list_files,function(x) read_excel(x)[,2]))
tsmom<-xts(tsmom[,1:5],order.by = seq(as.Date("2005-02-01"),length=183,by="months")-1)
names(tsmom)<-c("tsmom121","tsmom123","tsmom126","tsmom129","tsmom1212")
## newey west
newey_west<-function(x){
model<-lm(x~1)
newey_west<-coeftest(model,vcov=NeweyWest(model,verbose=T))
newey_west[c(1,3,4)]
}
## running newey west
cs_nw_full<-do.call(cbind,lapply(tsmom,newey_west))
library(gtools)
p_values<-cs_nw_full[3,]
cs_nw_full[2,]<-paste0(cs_nw_full[2,],stars.pval(p_values))
write.xlsx(cs_nw_full,"list_file.xlsx")
}
Try:
write.xlsx(cs_nw_full, paste0(eval(substitute(list_files)), ".xlsx"))
Edit:
#jeetkamal is absolutely right - you need to use
write.xlsx(cs_nw_full, paste0(deparse(substitute(list_files)), ".xlsx"))
here.
I apologize for the mistake. eval wold only work if list_files was e.g. the name of a file, not a list object.

How to use a list name as character

I would like to train a model and give it a name. I would like to use this name as character as well to create a text file with model summary. So I created a function as below
C50Training<-function(ModeName,DF_Trai,Form,
Str_PathSum){
library(C50);
ModeName<-C5.0(formula=Form,data=DF_Trai);
capture.output(summary(ModeName),file=paste(Str_PathSum,"/Summ",ModeName,".txt",sep=""));
}
In the funtion I want to use ModeName as characters. I tried to run it but it does not work. ModelName is a list in this case. How can I use ModelName as character?
To change a variable name to string, you can use deparse and substitute, as follows:
deparse(substitute(ModeName))
It return "ModeName" that can be part of your file path.
I tried this. It works.
ModeName=c(1,2,3)
f<-function(ModeName){
print(paste("/Summ",deparse(substitute(ModeName)),".txt",sep=""))
}
f(ModeName)
and this works too:
ModeName=c(1,2,3)
f<-function(list){
print(paste("/Summ",deparse(substitute(list)),".txt",sep=""))
}
f(ModeName)

How to pass function arguments to R model object

I would like to pass function arguments to R glm model objects. However, it seems my code below didnot work as R didn't recognize the passing argument.
I kept getting the error: non-numeric argument to binary operator
grid = (cbind(c('wl', 'livingd', 'deceasedt'), c('wl_time', 'ld_time', 'dec_time')))
for (k in 1:nrow(grid)){
f=function(y=as.name(grid[k,1]), offset=as.name(grid[k,2])){
m=glm(y~chain_class2+sex_new+age_cat+race_new,
family=poisson(link='log'),
data=poissonset,
offset=log(offset/12))
}
}
Is there a way to pass the variable names to the function? Thank you!
Try this:
grid = (cbind(c('wl', 'livingd', 'deceasedt'), c('wl_time', 'ld_time', 'dec_time')))
for (k in 1:nrow(grid)){
f=function(y=as.name(grid[k,1]), offset=as.name(grid[k,2])){
m=glm(get(y)~chain_class2+sex_new+age_cat+race_new,
family=poisson(link='log'),
data=poissonset,
offset=log(get(offset)/12))
}
}

Loop works outside function but in functions it doesn't.

Been going around for hours with this. My 1st question online on R. Trying to creat a function that contains a loop. The function takes a vector that the user submits like in pollutantmean(4:6) and then it loads a bunch of csv files (in the directory mentioned) and binds them. What is strange (to me) is that if I assign the variable id and then run the loop without using a function, it works! When I put it inside a function so that the user can supply the id vector then it does nothing. Can someone help ? thank you!!!
pollutantmean<-function(id=1:332)
{
#read files
allfiles<-data.frame()
id<-str_pad(id,3,pad = "0")
direct<-"/Users/ped/Documents/LearningR/"
for (i in id) {
path<-paste(direct,"/",i,".csv",sep="")
file<-read.csv(path)
allfiles<-rbind(allfiles,file)
}
}
Your function is missing a return value. (#Roland)
pollutantmean<-function(id=1:332) {
#read files
allfiles<-data.frame()
id<-str_pad(id,3,pad = "0")
direct<-"/Users/ped/Documents/LearningR/"
for (i in id) {
path<-paste(direct,"/",i,".csv",sep="")
file<-read.csv(path)
allfiles<-rbind(allfiles,file)
}
return(allfiles)
}
Edit:
Your mistake was that you did not specify in your function what you want to get out from the function. In R, you create objects inside of function (you could imagine it as different environment) and then specify which object you want it to return.
With my comment about accepting my answer, I meant this: (...To mark an answer as accepted, click on the check mark beside the answer to toggle it from greyed out to filled in...).
Consider even an lapply and do.call which would not need return being last line of function:
pollutantmean <- function(id=1:332) {
id <- str_pad(id,3,pad = "0")
direct_files <- paste0("/Users/ped/Documents/LearningR/", id, ".csv")
# READ FILES INTO LIST AND ROW BIND
allfiles <- do.call(rbind, lapply(direct_files, read.csv))
}
ok, I got it. I was expecting the files that are built to be actually created and show up in the environment of R. But for some reason they don't. But R still does all the calculations. Thanks lot for the replies!!!!
pollutantmean<-function(directory,pollutant,id)
{
#read files
allfiles<-data.frame()
id2<-str_pad(id,3,pad = "0")
direct<-paste("/Users/pedroalbuquerque/Documents/Learning R/",directory,sep="")
for (i in id2) {
path<-paste(direct,"/",i,".csv",sep="")
file<-read.csv(path)
allfiles<-rbind(allfiles,file)
}
#averaging polutants
mean(allfiles[,pollutant],na.rm = TRUE)
}
pollutantmean("specdata","nitrate",23:35)

Insert variable name into a function in R

I'm trying to construct a function that calculate some variances using the survey package. The problem is that I need to insert the name of the variable (not the values of the variables) into a specific function (svyby)
Is something like this:
myfun=function(variable) {
svyby(~variable,~subpop,design,svymean)
}
myfun(P16)
It gives me error. I also tried with
*base[,variable]*
instead of
*variable*
the problem here that base[,variable] gives me the vector with the values of the variable, but I need the name of the variable to be read in the design object. What I mean is, I need that the function insert the name like this
svyby(~P16,~subpop,design,svymean)
I will appreciate any help, thank you in advance,
Gonzalo
Looks like it needs a formula. You can paste a "~" to a string and use as.formula, like this:
myfun = function(variable) {
svyby(as.formula(paste("~", variable)),
~subpop, design, svymean)
}
And then call is like this: myfun("P16"). Note that you will need to use a quoted column name because you are treating it like a string.
Alternatively, you could have your function take a formula:
myfun2 = function(formula) {
svyby(formula,
~subpop, design, svymean)
}
And call it like this: myfun2(~P16).

Resources