我在数据表中有一个列,它是一个逗号分隔值列表
dt = data.table( a = c('a','b','c'), b = c('xx,yy,zz','mm,nn','qq,rr,ss,tt'))
> dt
a b
1: a xx,yy,zz
2: b mm,nn
3: c qq,rr,ss,tt
我想将其转换为长格式
a b
1: a xx
2: a yy
3: a zz
4: b mm
5: b nn
6: c qq
7: c rr
8: c ss
9: c tt
已针对数据框here回答了此问题。我想知道是否有一个优雅的数据表解决方案。
答案 0 :(得分:1)
以下内容适用于您的示例:
dt[, c(b=strsplit(b, ",")), by=a]
a b
1: a xx
2: a yy
3: a zz
4: b mm
5: b nn
6: c qq
7: c rr
8: c ss
9: c tt
如果在
中重复“by”变量,则此方法失败dt = data.table(a = c('a','b','c', 'a'),
b = c('xx,yy,zz','mm,nn','qq,rr,ss,tt', 'zz,gg,tt'))
在这种情况下,可以使用strsplit
分割变量并构建新的data.tabe
,从而获得一个强大的解决方案。 ID变量适当地循环使用填充缺失值的NA。然后使用is.na
删除包含NA的行。
data.table(a=dt[,a], b=unlist(strsplit(dt[,b], ",")))[!is.na(b)]
a b
1: a xx
2: b mm
3: c qq
4: a zz
5: a yy
6: b nn
7: c rr
8: a gg
9: a zz
10: c ss
11: a tt
12: c tt
答案 1 :(得分:1)
还有另一种方法,但是此方法涉及另一个包:splitstackshape。
library(splitstackshape)
cSplit(dt, "b", sep = ",", direction = "long")
a b
1: a xx
2: a yy
3: a zz
4: b mm
5: b nn
6: c qq
7: c rr
8: c ss
9: c tt
此功能使用data.table进行工作。即使我们对“ a”列具有多个相同的值,这项工作也可以实现。
答案 2 :(得分:-2)
我们可以split
列'b'用分隔符','(使用strsplit
),按'a'分组并设置新列的名称,即'V1'到'b 'with setnames
setnames(dt[, strsplit(b, ','), by = a], "V1", "b")[]
# a b
#1: a xx
#2: a yy
#3: a zz
#4: b mm
#5: b nn
#6: c qq
#7: c rr
#8: c ss
#9: c tt
如果'a'中有重复元素,如下例所示
dt <- data.table(a = c('a','b','c', 'a'),
b = c('xx,yy,zz','mm,nn','qq,rr,ss,tt', 'zz,gg,tt'))
我们可以按行序列进行分组,对'b'进行strsplit
,与'a'列连接,并将':=
)'grp'分配给NULL
dt[, c(a=a, b=strsplit(b, ",")), .(grp = 1:nrow(dt))][, grp := NULL][]
# a b
# 1: a xx
# 2: a yy
# 3: a zz
# 4: b mm
# 5: b nn
# 6: c qq
# 7: c rr
# 8: c ss
# 9: c tt
#10: a zz
#11: a gg
#12: a tt
注意:这两种方法都是data.table
方法