在我的表中,一些单元格是向量而不是单个值,即列是列表而不是向量:
dt1 <- data.table(
colA= c('A1','A2','A3'),
colB=list('B1',c('B2a','B2b'),'B3'),
colC= c('C1','C2','C3'),
colD= c('D1','D2','D3')
)
dt1
# colA colB colC colD
#1: A1 B1 C1 D1
#2: A2 B2a,B2b C2 D2
#3: A3 B3 C3 D3
我需要将其重新整形为长列格式,而不是列colB
列。到目前为止,我这样做:
dt1[,.(colB=unlist(colB)),by=.(colA,colC,colD)]
# colA colC colD colB
#1: A1 C1 D1 B1
#2: A2 C2 D2 B2a
#3: A2 C2 D2 B2b
#4: A3 C3 D3 B3
它完成了这项工作,但我不喜欢我必须在by=
中明确指出所有其他列名。有更好的方法吗?
(我确定它已在其他地方得到解答,但到目前为止我还无法找到它)
P.S。理想情况下,我想在没有任何外部包的情况下进行管理
答案 0 :(得分:8)
我认为@ Jaap是最简单的,但这是另一种咀嚼的选择:
#create ID column
dt1[ , ID := .I]
#unnest colB, keep ID column
dt_unnest = dt1[ , .(ID = rep(ID, lengths(colB)),
colB = unlist(colB))]
#merge
dt_unnest = dt_unnest[dt1[ , !'colB'], on = 'ID']
# ID colB colA colC colD
# 1: 1 B1 A1 C1 D1
# 2: 2 B2a A2 C2 D2
# 3: 2 B2b A2 C2 D2
# 4: 3 B3 A3 C3 D3
答案 1 :(得分:7)
将我的评论推荐给答案。使用:
dt1[,.(colB = unlist(colB)), by = setdiff(names(dt1), 'colB')]
给出:
colA colC colD colB 1: A1 C1 D1 B1 2: A2 C2 D2 B2a 3: A2 C2 D2 B2b 4: A3 C3 D3 B3
或作为替代方案(@ Frank提议的略微变化):
dt1[rep(dt1[,.I], lengths(colB))][, colB := unlist(dt1$colB)][]