我的问题是关于在向data.table分配多列时代码的易错性/可维护性。
我有一个返回像这样的data.table的函数:
f <- function(x)
{
# perform some complicated operations on x yielding multiple results
data.table(col1 = my_result_1, col2 = my_result_2)
}
我将此功能应用于另一个data.table的行组,并将结果添加为新列(或更新已存在的列):
dt <- data.table(x = 1 : 4, id = c(1,1,2,2))
# x id
# 1: 1 1
# 2: 2 1
# 3: 3 2
# 4: 4 2
dt[, c('col1', 'col2') := f(x), by = id]
从技术上讲,这可以正常工作。但是,我想知道是否有一种优雅的方法来避免必须在:=的LHS上再次指定在f()
中生成的列名。
答案 0 :(得分:0)
OP要求使用一种优雅的方法,避免在:=
的LHS上再次指定f()中生成的列名。
下面的方法既不优雅也不高效,但是避免了创建新的列名,并且如果修改了该函数以返回更多列或更改了输出列名,该方法将起作用,因此,它解决了问题错误提高了代码的易错性/可维护性 OP已经提出。
library(data.table)
f <- function(x) {
my_result_1 <- x^2/sum(x)
my_result_2 <- sum(x)/x
data.table(col1 = my_result_1, col2 = my_result_2)
}
dt <- data.table(x = 1 : 4, id = c(1,1,2,2))
tmp <- dt[, f(x), by = id]
dt[, names(tmp) := tmp]
dt[]
x id col1 col2 1: 1 1 0.3333333 3.000000 2: 2 1 1.3333333 1.500000 3: 3 2 1.2857143 2.333333 4: 4 2 2.2857143 1.750000
现在,让我们重新定义f()
f <- function(x) {
my_result_1 <- x^2/sum(x)
my_result_2 <- sum(x)/x
my_result_3 <- max(x)/x
data.table(c1 = my_result_1, c2 = my_result_2, c3 = my_result_3)
}
tmp <- dt[, f(x), by = id]
dt[, names(tmp) := tmp]
dt[]
x id col1 col2 c1 c2 c3 1: 1 1 0.3333333 3.000000 0.3333333 3.000000 2.000000 2: 2 1 1.3333333 1.500000 1.3333333 1.500000 1.000000 3: 3 2 1.2857143 2.333333 1.2857143 2.333333 1.333333 4: 4 2 2.2857143 1.750000 2.2857143 1.750000 1.000000
与pointed out by Frank一样,仅当f(x)
返回与dt
相同的行数时,此答案才有效。