data.table分配多个列作为新的data.table(或列表)生成,而无需重复名称

时间:2018-08-15 14:48:26

标签: r data.table names

我的问题是关于在向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()中生成的列名。

1 个答案:

答案 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相同的行数时,此答案才有效。