从一个函数计算多个列并将它们添加到data.frame

时间:2014-12-29 20:07:15

标签: r data.table dplyr

我想从data.frame列上的函数返回多个结果,并将这些新列与其他简单计算一起添加到同一data.frame

对于一个简化的例子,如果我想得到sin函数的积分值和绝对误差以及积分区间的中点:

df <- data.frame(Lower = c(1,2,3), Upper = c(2,3,4))
setDT(df)
getIntegral <- function(l, u) {
  n <- integrate(sin, mean(l), mean(u))
  list(Value=n$value, Error=n$abs.error)
}
df[,
   c('Value', 'Error', 'Mid') := {
     n <- getIntegral(Lower, Upper)
     list(n$Value,
          n$Error,
          (Lower+Upper)/2)
   }]
df
   Lower Upper     Value        Error Mid
1:     1     2 0.5738457 6.370967e-15 1.5
2:     2     3 0.5738457 6.370967e-15 2.5
3:     3     4 0.5738457 6.370967e-15 3.5

我不太喜欢我的方法,因为分隔新列的名称和分配给它们的值使我很难阅读,我怎样才能更好地完成这项任务?它是长数据处理链的一部分,所以我不想在外面创建临时变量,所以我更喜欢单独使用data.tabledplyr的解决方案。

1 个答案:

答案 0 :(得分:6)

RHS应该是值列表,列表的每个元素都会转换为列(如果需要,可以回收)。

您的函数已经返回list(每个长度为1),(Lower+Upper)/2返回3个值的向量(此处)。要返回列表,您可以使用函数c(),如下所示:

df[, c('Value', 'Error', 'Mid') := c(getIntegral(Lower, Upper), list((Lower+Upper)/2))]
#    Lower Upper     Value        Error Mid
# 1:     1     2 0.5738457 6.370967e-15 1.5
# 2:     2     3 0.5738457 6.370967e-15 2.5
# 3:     3     4 0.5738457 6.370967e-15 3.5

这利用了c(list, list)导致连续列表的事实。