简体   繁体   中英

How to create list of functions with multiple parameters from dataframes in R?

Long time reader, first time poster. I have not found any previous questions about my current problem. I would like to create multiple linear functions, which I can later apply to variables. I have a data frame of slopes: df_slopes and a data frame of constants: df_constants. Dummy data:

df_slope <- data.frame(var1 = c(1, 2, 3,4,5), var2 = c(2,3,4,5,6), var3 = c(-1, 1, 0, -10, 1))
df_constant<- data.frame(var1 = c(3, 4, 6,7,9), var2 = c(2,3,4,5,6), var3 = c(-1, 7, 8, 0, -1))

I would like to construct functions such as

myfunc <- function(slope, constant, trvalue){
result <- trvalue*slope+constant
return(result)}

where the slope and constant values are

slope<- df_slope[i,j]
constant<- df_constant[i,j]

I have tried many ways, for example like this, creating a dataframe of functions with for loop

myfunc_all<-data.frame()
for(i in 1:5){
   for(j in 1:3){
     myfunc_all[i,j]<-function (x){ x*df_slope[i,j]+df_constant[i,j] }
     full_func[[i]][j]<- func_full
   }
  }

without success. The slope-constant values are paired up, such as df_slope[i,j] is paired with df_constant[i,j]. The desired end result would be some kind of data frame, from where I can call a function by giving it the coordinates, for example like this: myfunc_all[i,j} but any form would be great. For example

myfunc_all[2,1]

in our case would be

function (x){ x*2+4] 

which I can apply to different x values. I hope my problem is clear.

df_slope <- data.frame(var1 = c(1, 2, 3,4,5), var2 = c(2,3,4,5,6), var3 = c(-1, 1, 0, -10, 1))
df_constant<- data.frame(var1 = c(3, 4, 6,7,9), var2 = c(2,3,4,5,6), var3 = c(-1, 7, 8, 0, -1))

functions  = vector(mode = "list", length = nrow(df_slope))

for (i in 1:nrow(df_slope)) {
  functions[[i]] = function(i,x) { df_slope[i]*x + df_constant[i]}
}

f = function(i, x) {
  functions[[i]](i, x)
}

f(1, 1:10)
f(3, 5:10)

So you have a slight problem with lazy evaluation and variable scopes when you are using a for loop to build functions (see here for more info). It's a bit safer to use something like mapply which will create closures for you. Try

myfunc_all <- with(expand.grid(1:5, 1:3), mapply(function(i, j) {
  function(x) {
    x*df_slope[i,j]+df_constant[i,j]
  }
},Var1, Var2))
dim(myfunc_all) <- c(5,3)

This will create an array like object. The only difference is that you need to use double brackets to extract the function. For example

myfunc_all[[2,1]](0)
# [1] 4
myfunc_all[[5,3]](0)
# [1] -1

Alternative you can choose to write a function that returns a function. That would look like

myfunc_all <- (function(slopes, constants) {
  function(i, j)
    function(x) x*slopes[i,j]+constants[i,j]
})(df_slope, df_constant)

then rather than using brackets, you call the function with parenthesis.

myfunc_all(2,1)(0)
# [1] 4
myfunc_all(5,3)(0)
# [1] -1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM