如何从data.table的列表列提取值并分配至不同列?
如何将data.table列中的列表数据拆分到不同列?
你遇到的问题其实是因为用l[[1]]时,取的是整个列表列的第一个元素,而非每行列表元素里的对应值,所以所有行都复用了第一行的结果。下面给你几种高效的正确实现方法:
方法1:用transpose(最简洁高效)
data.table的transpose()函数专门处理这种列表转列的场景,直接把列表中的每个向量转成对应列:
require(data.table) d <- data.table(id=1:3,l=list(c(1,2),c(5,6),c(7,9))) d[, c("l1", "l2") := transpose(l)]
执行后就能得到你想要的结果:
# id l l1 l2 # 1: 1 1,2 1 2 # 2: 2 5,6 5 6 # 3: 3 7,9 7 9
方法2:用sapply逐位置提取
如果需要更灵活控制提取位置,可以用sapply遍历列表列的每个元素,提取对应位置的值:
d[, c("l1", "l2") := .(sapply(l, `[`, 1), sapply(l, `[`, 2))]
要是列表长度固定(比如这里是2),还可以用循环简化写法:
d[, c("l1", "l2") := lapply(1:2, function(i) sapply(l, `[`, i))]
方法3:转成矩阵再拆分
把列表中的向量拼成矩阵,再转成data.table赋值:
d[, c("l1", "l2") := as.data.table(do.call(rbind, l))]
为什么原来的代码出错?
你之前写的d[,':='(l1 = l[[1]][1],l2=l[[1]][2])]中,l[[1]]是从整个l列(一个长度为3的列表)里取出第一个元素c(1,2),再取它的第1/2个值,最终l1和l2都是固定的1和2,并没有实现逐行提取。
内容的提问来源于stack exchange,提问作者katsumi
相关产品推荐
相关产品推荐

