0

I am learning how to run functions. Hopefully, this would be an easy question to answer.

I have a df and I want to pass the function w to some of the variables in the df.

df <- data.frame(id= c(1,1,1,2,2,2,3,3,3), time=c(1,2,3,1,2,3,1,2,3),y = rnorm(9), x1 = rnorm(9), x2 = c(0,0,0,0,1,0,1,1,1),c2 = rnorm(9))
library(data.table)
library(dplyr)

w<-function(data,var1,var2){
  x <- substitute(var1)
  y <- substitute(var2)
  data<-setDT(data)[,paste("times",(var1), (var2), sep = "_"):=eval(var1)*eval(var2)]
}

df2<- w(df,y,x1)  

When I apply the function to a single variable the function works. but I would like to apply it to a series of variables in my data frame, but for some reason, the function fails when I try to apply it to multiple variables at once. does anyone know how I could make it work?

So far I tried the following

vars<-c("x1","x2")
df3<- lapply(vars, function(x) w(df,y, x))

thanks a lot for your help

1 Answer 1

1

data.table works well with variable names. You use get to unquote names and get them evaluated in the scope of the data.table object. I wrote a blog post exactly on that subject, if it can help you.

df <- data.frame(id= c(1,1,1,2,2,2,3,3,3), time=c(1,2,3,1,2,3,1,2,3),y = rnorm(9), x1 = rnorm(9), x2 = c(0,0,0,0,1,0,1,1,1),c2 = rnorm(9))

library(data.table)
setDT(df)

Your function can be simplified to:

w <- function(data, var1, var2){
  if (!inherits(data, "data.table")){
        setDT(data)
  }
  data[,(paste("times",var1,var2, sep = "_")) := get(var1)*get(var2)]
}

And you call it by using variable names

vars<-c("x1","x2")
lapply(vars, function(x) w(df,"y", x))


df
   id time           y         x1 x2          c2 times_y_x1 times_y_x2
1:  1    1 -0.81438357  0.4493933  0 -0.39143328 -0.3659786  0.0000000
2:  1    2  0.36358498 -1.3574671  0  0.06062278 -0.4935547  0.0000000
3:  1    3  0.04049807  0.2860555  0  1.58123937  0.0115847  0.0000000
4:  2    1  0.15490901 -0.8654069  0 -1.09874917 -0.1340593  0.0000000
5:  2    2 -0.87899821  0.2863604  1 -0.73161360 -0.2517103 -0.8789982
6:  2    3  0.37881104  1.6135654  0  1.30268569  0.6112364  0.0000000
7:  3    1 -0.72990680  0.5867623  1  0.41856548 -0.4282818 -0.7299068
8:  3    2 -0.53344035  0.5073415  1  0.64326809 -0.2706364 -0.5334404
9:  3    3 -0.27674109 -0.5226920  1 -2.28723895  0.1446504 -0.2767411

Note that you update your dataframe since you use := so you don't need to reassign the output

Sign up to request clarification or add additional context in comments.

4 Comments

I am trying to use the function, but it fails to save into the object.. it says Error: unexpected '}' in "}"
Sorry, it was the if statement that was responsible. You can try again
Thanks a lot, it works very well! can I ask you what does the if (!inherits(data, "data.table")){setDT(data) statement is about? so I know what is going on and able to run it again with new issues. Also thank you for pointing me the blog post! I will look at it closely!
You're welcome. This is to change to a data.table type only if the object is not a data.table and not at every iteration of the lapply loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.