在嵌套的data.table中通过引用修改列表列

时间:2017-10-09 14:56:09

标签: r data.table

在嵌套data.table中使用data.tables的列表列时,可以很容易地在列上应用函数。例如:

dt<- data.table(mtcars)[, list(dt.mtcars = list(.SD)), by = gear]

我们可以使用:

dt[ ,list(length = nrow(dt.mtcars[[1]])), by = gear]

dt[ ,list(length = nrow(dt.mtcars[[1]])), by = gear]

   gear length
1:    4     12
2:    3     15
3:    5      5

dt[, list( length = lapply(dt.mtcars, nrow)), by = gear]

  gear length
1:    4     12
2:    3     15
3:    5      5

我想做同样的过程,并使用运算符:=通过引用对列的每个data.table应用修改。

示例:

modify_by_ref<- function(d){

  d[, max_hp:= max(hp)]


}

dt[, modify_by_ref(dt.mtcars[[1]]), by  = gear]

返回错误:

 Error in `[.data.table`(d, , `:=`(max_hp, max(hp))) : 
  .SD is locked. Using := in .SD's j is reserved for possible future use; a tortuously flexible way to modify by group. Use := in j directly to modify by group by reference. 

使用错误消息中的提示对我来说不起作用,它似乎针对另一个案例,但也许我错过了一些东西。是否有任何推荐的方法或灵活的解决方法来通过refence修改列表列?

1 个答案:

答案 0 :(得分:1)

这可以通过以下两个步骤或单步执行:

给定的表是:

dt<- data.table(mtcars)[, list(dt.mtcars = list(.SD)), by = gear]

第1步 - 让我们在hp

的每一行中添加列dt向量列表
dt[, hp_vector := .(list(dt.mtcars[[1]][, hp])), by = list(gear)]

第2步 - 现在计算hp

的最大值
dt[, max_hp := max(hp_vector[[1]]), by = list(gear)]

给定的表是:

dt<- data.table(mtcars)[, list(dt.mtcars = list(.SD)), by = gear]

单步 - 单步实际上是上述两个步骤的组合:

dt[, max_hp := .(list(max(dt.mtcars[[1]][, hp])[[1]])), by = list(gear)]

如果我们希望通过Reference在嵌套表中填充值,那么以下链接将讨论如何执行此操作,只需要忽略警告消息。如果有人能指出我如何修复警告信息或有任何陷阱,我会很高兴。有关更多详细信息,请参阅链接:

https://stackoverflow.com/questions/48306010/how-can-i-do-fast-advance-data-manipulation-in-nested-data-table-data-table-wi/48412406#48412406

从相同的灵感中获取灵感我将在这里展示如何针对给定的数据集进行操作。

让我们先清理一切:

rm(list = ls())

让我们以不同的方式重新定义给定的表:

dt<- data.table(mtcars)[, list(dt.mtcars = list(data.table(.SD))), by = list(gear)]

请注意,我已经定义了略有不同的表格。除了上面定义中的列表之外,我还使用了data.table

接下来,在嵌套表中按引用填充max:

dt[, dt.mtcars := .(list(dt.mtcars[[1]][, max_hp := max(hp)])), by = list(gear)]

而且,我们可以在嵌套表中执行操作:

dt[, dt.mtcars := .(list(dt.mtcars[[1]][, weighted_hp_carb := max_hp*carb])), by = list(gear)]