I have a list of functions
我有一个功能列表
funs <- list(fn1 = function(x) x^2,
fn2 = function(x) x^3,
fn3 = function(x) sin(x),
fn4 = function(x) x+1)
#in reality these are all f = splinefun()
And I have a dataframe:
我有一个数据帧:
mydata <- data.frame(x1 = c(1, 2, 3, 2),
x2 = c(3, 2, 1, 0),
x3 = c(1, 2, 2, 3),
x4 = c(1, 2, 1, 2))
#actually a 500x15 dataframe of 500 samples from 15 parameters
For each of i rows, I would like to evaluate function j on each of the j columns and sum the results:
对于i行中的每一行,我想评估每个j列上的函数j并对结果求和:
unlist(funs)
attach(mydata)
a <- rep(NA,4)
for (i in 1:4) {
a[i] <- sum(fn1(x1[i]), fn2(x2[i]), fn3(x3[i]), fn4(x4[i]))
}
How can I do this efficiently? Is this an appropriate occasion to implement plyr
functions? If so, how?
我怎样才能有效地做到这一点?这是实施plyr功能的适当时机吗?如果是这样,怎么样?
bonus question: why is a[4]
NA
?
奖金问题:为什么是[4] NA?
Is this an appropriate time to use functions from plyr
, if so, how can I do so?
这是使用plyr函数的合适时间,如果是,我该怎么办?
3 个解决方案
#1
9
Ignoring your code snippet and sticking to your initial specification that you want to apply function j on the column number j and then "sum the results"... you can do:
忽略你的代码片段并坚持你想要在列号j上应用函数j的初始规范然后“求和结果”......你可以这样做:
mapply( do.call, funs, lapply( mydata, list))
# [,1] [,2] [,3] [,4]
# [1,] 1 27 0.8414710 2
# [2,] 4 8 0.9092974 3
# [3,] 9 1 0.9092974 3
I wasn't sure which way you want to now add the results (i.e. row-wise or column-wise), so you could either do rowSums
or colSums
on this matrix. E.g:
我不确定你现在想要以哪种方式添加结果(即逐行或逐列),因此你可以在这个矩阵上做rowSums或colSums。例如:
colSums( mapply( do.call, funs, lapply( mydata, list)) )
# [1] 14.000000 36.000000 2.660066 8.000000
#2
4
Why don't just write one function for all 4 and apply it to the data frame? All your functions are vectorized, and so is splinefun
, and this will work:
为什么不为所有4编写一个函数并将其应用于数据框?你的所有函数都是矢量化的,splinefun也是如此,这样就可以了:
fun <- function(df)
cbind(df[, 1]^2, df[, 2]^3, sin(df[, 3]), df[, 4] + 1)
rowSums(fun(mydata))
This is considerably more efficient than "foring" or "applying" over the rows.
这比在行上“强制”或“应用”要高效得多。
#3
0
I tried using plyr::each
:
我尝试使用plyr :: each:
library(plyr)
sapply(mydata, each(min, max))
x1 x2 x3 x4
min 1 0 1 1
max 3 3 3 2
and it works fine, but when I pass custom functions I get:
它工作正常,但当我通过自定义函数时,我得到:
sapply(mydata, each(fn1, fn2))
Error in proto[[i]] <- fs[[i]](x, ...) :
more elements supplied than there are to replace
each
has very brief documentation, I don't quite get what's the problem.
每个都有非常简短的文档,我不太明白这是什么问题。
#1
9
Ignoring your code snippet and sticking to your initial specification that you want to apply function j on the column number j and then "sum the results"... you can do:
忽略你的代码片段并坚持你想要在列号j上应用函数j的初始规范然后“求和结果”......你可以这样做:
mapply( do.call, funs, lapply( mydata, list))
# [,1] [,2] [,3] [,4]
# [1,] 1 27 0.8414710 2
# [2,] 4 8 0.9092974 3
# [3,] 9 1 0.9092974 3
I wasn't sure which way you want to now add the results (i.e. row-wise or column-wise), so you could either do rowSums
or colSums
on this matrix. E.g:
我不确定你现在想要以哪种方式添加结果(即逐行或逐列),因此你可以在这个矩阵上做rowSums或colSums。例如:
colSums( mapply( do.call, funs, lapply( mydata, list)) )
# [1] 14.000000 36.000000 2.660066 8.000000
#2
4
Why don't just write one function for all 4 and apply it to the data frame? All your functions are vectorized, and so is splinefun
, and this will work:
为什么不为所有4编写一个函数并将其应用于数据框?你的所有函数都是矢量化的,splinefun也是如此,这样就可以了:
fun <- function(df)
cbind(df[, 1]^2, df[, 2]^3, sin(df[, 3]), df[, 4] + 1)
rowSums(fun(mydata))
This is considerably more efficient than "foring" or "applying" over the rows.
这比在行上“强制”或“应用”要高效得多。
#3
0
I tried using plyr::each
:
我尝试使用plyr :: each:
library(plyr)
sapply(mydata, each(min, max))
x1 x2 x3 x4
min 1 0 1 1
max 3 3 3 2
and it works fine, but when I pass custom functions I get:
它工作正常,但当我通过自定义函数时,我得到:
sapply(mydata, each(fn1, fn2))
Error in proto[[i]] <- fs[[i]](x, ...) :
more elements supplied than there are to replace
each
has very brief documentation, I don't quite get what's the problem.
每个都有非常简短的文档,我不太明白这是什么问题。