对数据帧的每一行应用多个函数

每次我觉得我理解与向量工作时,似乎是一个简单的问题,我的头脑里面就出来了。很多阅读和尝试不同的例子在这个时候没有帮助。请勺子给我在这里

我想对数据帧的每一行应用两个自定义函数,并将结果添加为两个新列。这是我的示例代码:

# Required packages:
library(plyr)

FindMFE <- function(x) {
    MFE <- max(x, na.rm = TRUE) 
    MFE <- ifelse(is.infinite(MFE ) | (MFE  < 0), 0, MFE)
    return(MFE)
}

FindMAE <- function(x) {
    MAE <- min(x, na.rm = TRUE) 
    MAE <- ifelse(is.infinite(MAE) | (MAE> 0), 0, MAE)
    return(MAE)
}

FindMAEandMFE <- function(x){
        # I know this next line is wrong...
    z <- apply(x, 1, FindMFE, FindMFE)
        return(z)
}

df1 <- data.frame(Bar1=c(1,2,3,-3,-2,-1),Bar2=c(3,1,3,-2,-3,-1))

df1 = transform(df1, 
    FindMAEandMFE(df1)  
)

#DF1 should end up with the following data...
#Bar1   Bar2    MFE MAE
#1      3       3   0
#2      1       2   0
#3      3       3   0
#-3     -2      0   -3
#-2     -3      0   -3
#-1     -1      0   -1

使用plyr库和更基础的方法来获取答案是非常好的。两者都有助于我的理解。当然,请指出如果明显的话我会出错。 😉

现在回到我的帮助文件!

编辑:我想要一个多变量解决方案,因为列名可能会随着时间的推移而改变和扩展。它还允许将来重新使用代码。

我想你在这里太复杂了。两个单独的apply()调用有什么问题?然而,做一个更好的方法是在这里做,这不涉及循环/应用呼叫。我将分别处理这些,但是第二个解决方案是比较好的,因为它是真正的矢量化的。

两个应用电话版本

使用全部Base R功能的前两个单独的应用调用:

df1 <- data.frame(Bar1=c(1,2,3,-3,-2,-1),Bar2=c(3,1,3,-2,-3,-1))
df1 <- transform(df1, MFE = apply(df1, 1, FindMFE), MAE = apply(df1, 1, FindMAE))
df1

这使:

> df1
  Bar1 Bar2 MFE MAE
1    1    3   3   0
2    2    1   2   0
3    3    3   3   0
4   -3   -2   0  -3
5   -2   -3   0  -3
6   -1   -1   0  -1

好的,循环遍历df1的两行可能有点低效,但即使是大问题,你花了更多的时间思考如何巧妙地在一个单一的过程中比通过这样做来节省。

使用矢量化函数pmax()和pmin()

所以一个更好的方法是注意pmax()和pmin()函数,并意识到他们可以做各种应用(df1,1,FindFOO()调用都在做,例如:

> (tmp <- with(df1, pmax(0, Bar1, Bar2, na.rm = TRUE)))
[1] 3 2 3 0 0 0

将是你的问题的MFE。如果您有两列,那么它们是非常简单的,它们是Bar1和Bar2,或者是始终为df1的前2列。但它不是很普遍;如果你有多个列要计算这个等等呢? pmax(df1 [,1:2],na.rm = TRUE)将不会做我们想要的:

> pmax(df1[, 1:2], na.rm = TRUE)
  Bar1 Bar2
1    1    3
2    2    1
3    3    3
4   -3   -2
5   -2   -3
6   -1   -1

使用pmax()和pmin()获取一般解决方案的诀窍是使用do.call()来安排对我们这两个函数的调用。更新您的功能以使用我们拥有的这个想法:

FindMFE2 <- function(x) {
   MFE <- do.call(pmax, c(as.list(x), 0, na.rm = TRUE))
   MFE[is.infinite(MFE)] <- 0
   MFE
}

FindMAE2 <- function(x) {
   MAE <- do.call(pmin, c(as.list(x), 0, na.rm = TRUE))
   MAE[is.infinite(MAE)] <- 0
   MAE
}

给出:

> transform(df1, MFE = FindMFE2(df1), MAE = FindMAE2(df1))
  Bar1 Bar2 MFE MAE
1    1    3   3   0
2    2    1   2   0
3    3    3   3   0
4   -3   -2   0  -3
5   -2   -3   0  -3
6   -1   -1   0  -1

而不是应用()。如果你想在一个步骤中这样做,现在更容易包装:

FindMAEandMFE2 <- function(x){
    cbind(MFE = FindMFE2(x), MAE = FindMAE2(x))
}

其可以用作:

> cbind(df1, FindMAEandMFE2(df1))
  Bar1 Bar2 MFE MAE
1    1    3   3   0
2    2    1   2   0
3    3    3   3   0
4   -3   -2   0  -3
5   -2   -3   0  -3
6   -1   -1   0  -1
http://stackoverflow.com/questions/7173895/apply-multiple-functions-to-each-row-of-a-dataframe

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:对数据帧的每一行应用多个函数