Ste*_* J. 5 r names data.table
我的问题是关于将多列分配给 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)
}
Run Code Online (Sandbox Code Playgroud)
我将此函数应用于另一个 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]
Run Code Online (Sandbox Code Playgroud)
从技术上讲,这很好用。但是,我想知道是否有一种优雅的方法可以避免在f():= 的 LHS 上再次指定生成的列名。
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[]
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)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[]
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)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
正如弗兰克所指出的f(x),只有当返回与 相同的行数时,这个答案才有效dt。