在数据框的列上进行 Strsplit
Strsplit on a column of a data frame
我有一个 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
.
中只出现一次
这种reshaping/unlisting/merging有什么好的方法吗?我想出了一个非常麻烦的 for
循环遍历 MyDF
和 strsplit(MyColumn,split=",")
对应元素的长度。我很确定必须有一种更优雅的方式。
您可以使用 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
怎么样
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
我们可以使用 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
我们也可以使用 do with base R
with strsplit
将 'cat' 列拆分为 list
,复制 'MyDF' 的行序列使用 'lst' 的 lengths
,并通过 unlist
ing 'lst'.
创建 'cat' 列
lst <- strsplit(as.character(MyDF$cat), ",")
transform(MyDF[rep(1:nrow(MyDF), lengths(lst)),-3], cat = unlist(lst))
我有一个 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
.
这种reshaping/unlisting/merging有什么好的方法吗?我想出了一个非常麻烦的 for
循环遍历 MyDF
和 strsplit(MyColumn,split=",")
对应元素的长度。我很确定必须有一种更优雅的方式。
您可以使用 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
怎么样
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
我们可以使用 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
我们也可以使用 do with base R
with strsplit
将 'cat' 列拆分为 list
,复制 'MyDF' 的行序列使用 'lst' 的 lengths
,并通过 unlist
ing 'lst'.
lst <- strsplit(as.character(MyDF$cat), ",")
transform(MyDF[rep(1:nrow(MyDF), lengths(lst)),-3], cat = unlist(lst))