我有一个data.frame
,其中一个变量是矢量(或列表),如下所示:
MyColumn <- c("A, B,C", "D,E", "F","G")
MyDF <- data.frame(group_id=1:4, val=11:14, cat=MyColumn)
# group_id val cat
# 1 1 11 A, B,C
# 2 2 12 D,E
# 3 3 13 F
# 4 4 14 G
我想要一个新的数据框,其行数与向量
相同FlatColumn <- unlist(strsplit(MyColumn,split=","))
看起来像这样:
MyNewDF <- data.frame(group_id=c(rep(1,3),rep(2,2),3,4), val=c(rep(11,3),rep(12,2),13,14), cat=FlatColumn)
# group_id val cat
# 1 1 11 A
# 2 1 11 B
# 3 1 11 C
# 4 2 12 D
# 5 2 12 E
# 6 3 13 F
# 7 4 14 G
实质上,对于作为MyColumn
列表元素(字母A到G)的每个因素,我想分配列表的相应值。每个因素仅在MyColumn
中出现一次。
这种重塑/不列名/合并是否有一种巧妙的方法?我在for
的行和 MyDF
的相应元素的长度上提出了一个非常繁琐的strsplit(MyColumn,split=",")
循环。我非常肯定必须有更优雅的方式。
答案 0 :(得分:6)
您可以使用separate_rows
中的tidyr
:
tidyr::separate_rows(MyDF, cat)
# group_id val cat
# 1 1 11 A
# 2 1 11 B
# 3 1 11 C
# 4 2 12 D
# 5 2 12 E
# 6 3 13 F
# 7 4 14 G
答案 1 :(得分:5)
怎么样
lst <- strsplit(MyColumn, split = ",")
k <- lengths(lst) ## expansion size
FlatColumn <- unlist(lst, use.names = FALSE)
MyNewDF <- data.frame(group_id = rep.int(MyDF$group_id, k),
val = rep.int(MyDF$val, k),
cat = FlatColumn)
# group_id val cat
#1 1 11 A
#2 1 11 B
#3 1 11 C
#4 2 12 D
#5 2 12 E
#6 3 13 F
#7 4 14 G
答案 2 :(得分:4)
我们可以使用cSplit
splitstackshape
library(splitstackshape)
cSplit(MyDF, "cat", ",", "long")
# group_id val cat
#1: 1 11 A
#2: 1 11 B
#3: 1 11 C
#4: 2 12 D
#5: 2 12 E
#6: 3 13 F
#7: 4 14 G
我们还可以使用base R
与strsplit
一起分割“猫”。将列放入list
,复制&#39; MyDF&#39;的行序列。使用&#39; lst&#39;的lengths
,并创建“猫”#39;通过unlist
&lt; lst&#39;。
lst <- strsplit(as.character(MyDF$cat), ",")
transform(MyDF[rep(1:nrow(MyDF), lengths(lst)),-3], cat = unlist(lst))