【发布时间】:2014-12-29 20:07:14
【问题描述】:
我想从 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.table 或 dplyr 的解决方案。
【问题讨论】:
-
你是说你不喜欢 data.table 语法??
-
你的意思是这样的吗?
setDT(df)[,":="(Value=getIntegral(Lower,Upper)$Value, Error=getIntegral(Lower,Upper)$Error, Mid =(Lower+Upper)/2)] -
或者这个??
setDT(df)[,c("Value","Rrror","Mid"):= with(getIntegral(Lower,Upper),list(Value,Error,(Lower+Upper)/2))] -
@jlhoward,我想要
setDT(df)[,":="(Value=getIntegral(Lower,Upper)$Value, Error=getIntegral(Lower,Upper)$Error, Mid =(Lower+Upper)/2)]之类的东西,但我不想运行getIntegral两次。 -
那就用第一种方法吧。或者,您可以更改函数以返回包含所有三个值(Value、Error 和 Mid)的命名列表,然后只需使用
setDT(df)[,getIntegral(Lower,Upper),by=list(Lower,Upper)]
标签: r data.table dplyr