将n个函数的列表应用于数据帧的每一行?

时间:2011-01-21 23:48:26

标签: r apply plyr

我有一个功能列表

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()

我有一个数据框:

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

对于每个 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]))
}

我该如何有效地做到这一点?这是实施plyr功能的适当时机吗?如果是这样,怎么样?

红利问题:为什么a[4] NA

这是使用plyr中的函数的合适时间吗?如果是,我该怎么办?

3 个答案:

答案 0 :(得分:9)

忽略您的代码段并坚持您要在列号 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

我不确定您希望现在添加结果的方式(即行方式或列方式),因此您可以在此矩阵上执行rowSumscolSums。 E.g:

colSums( mapply( do.call, funs,  lapply( mydata, list)) )
# [1] 14.000000 36.000000  2.660066  8.000000

答案 1 :(得分:4)

为什么不为所有4编写一个函数并将其应用于数据框? 你的所有函数都是矢量化的,splinefun也是如此,这将起作用:

fun <-  function(df)
    cbind(df[, 1]^2, df[, 2]^3, sin(df[, 3]), df[, 4] + 1)

rowSums(fun(mydata))

这比在行上“强制”或“应用”效率要高得多。

答案 2 :(得分:0)

我尝试使用plyr::each

library(plyr)
sapply(mydata, each(min, max))
    x1 x2 x3 x4
min  1  0  1  1
max  3  3  3  2

它工作正常,但当我通过自定义函数时,我得到:

sapply(mydata, each(fn1, fn2))
Error in proto[[i]] <- fs[[i]](x, ...) :
  more elements supplied than there are to replace

each有非常简短的文档,我不太明白这是什么问题。