Strsplit在数据框的一列上

时间:2016-08-18 23:08:27

标签: r dataframe reshape

我有一个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=",")循环。我非常肯定必须有更优雅的方式。

3 个答案:

答案 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 Rstrsplit一起分割“猫”。将列放入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))