如何在data.table中按引用创建分组聚合的signal实例列表列?
问题描述
给定如下data.table:
library(data.table) dt <- data.table( a=c(1,3,1,3,5:8) , b=c(2,4,2,4,9:12) , signal = c("up", "up", "down", "down") )
需求是创建一个列temp,列出每对a、b对应的所有signal实例。
以下非引用修改的代码可得到正确结果:
dt_out <- dt[ , .(temp = signal |> list(), signal) , .(a,b) ]
输出结果:
> dt_out a b temp signal <num> <num> <list> <char> 1: 1 2 up,down up 2: 1 2 up,down down 3: 3 4 up,down up 4: 3 4 up,down down 5: 5 9 up up 6: 6 10 up up 7: 7 11 down down 8: 8 12 down down
但尝试直接按引用创建temp列时,结果不符合预期:
dt[ , temp := signal |> list() , .(a,b)]
错误输出(temp并非列表类型):
> dt a b signal temp <num> <num> <char> <char> 1: 1 2 up up 2: 3 4 up up 3: 1 2 down down 4: 3 4 down down 5: 5 9 up up 6: 6 10 up up 7: 7 11 down down 8: 8 12 down down
请问如何修正,以实现在dt中按引用创建temp列?
解决方案
按组引用赋值时,signal |> list()仅生成一个包含当前组所有signal的单元素列表,data.table会自动拆解这个列表中的向量,按位置分配给组内每行,导致temp变成普通字符列。
要让temp成为存储每组所有signal的列表列,需确保每个组返回长度等于组内行数的列表,每个元素都是当前组的完整signal向量。修正代码如下:
dt[, temp := rep(list(signal), .N), by = .(a, b)]
执行后即可得到符合预期的结果:
> dt a b signal temp <num> <num> <char> <list> 1: 1 2 up up,down 2: 3 4 up up,down 3: 1 2 down up,down 4: 3 4 down up,down 5: 5 9 up up 6: 6 10 up up 7: 7 11 down down 8: 8 12 down down
关键说明
.N是data.table内置变量,代表当前组的行数;rep(list(signal), .N)将包含当前组signal的列表重复.N次,生成与组内行数匹配的列表,确保每行temp都存储该组全部signal实例。
内容的提问来源于stack exchange,提问作者Fabio Correa
相关产品推荐
相关产品推荐

