如何取消列出' data.table中的一列

时间:2017-06-02 20:11:53

标签: r data.table

在我的表中,一些单元格是向量而不是单个值,即列是列表而不是向量:

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。理想情况下,我想在没有任何外部包的情况下进行管理

2 个答案:

答案 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)][]