我有一张格式如下的表格。
df1 <- data.frame (A=c("aaa", "bbb", "ccc", "ddd"),
B=c("111; 222", "333", "444; 555; 666; 777", "888; 999"))
A B
1 aaa 111; 222
2 bbb 333
3 ccc 444; 555; 666; 777
4 ddd 888; 999
我想要一个这样的数据框:
aaa 111
aaa 222
bbb 333
ccc 444
ccc 555
ccc 666
ccc 777
ddd 888
ddd 999
我找到了一个很棒的解决方案,可以在之前的Stack Overflow问题中将类似的列表转换为数据帧。但是,我很难从具有多个条目的数据框转换它。我怎么能这样做?
答案 0 :(得分:8)
这是一个简单的基础R解决方案(下面的解释):
spl <- with(df1, strsplit(as.charcter(B), split = "; ", fixed = TRUE))
lens <- sapply(spl, length)
out <- with(df1, data.frame(A = rep(A, lens), B = unlist(spl)))
这给了我们:
R> out
A B
1 aaa 111
2 aaa 222
3 bbb 333
4 ccc 444
5 ccc 555
6 ccc 666
7 ccc 777
8 ddd 888
9 ddd 999
代码在做什么?第1行:
spl <- with(df1, strsplit(as.character(B), split = "; ", fixed = TRUE))
使用B
作为要拆分的字符,将"; "
中的每个字符串分开。我们在评论中使用fixed = TRUE
(由 @Marek 建议)来加速匹配和拆分,因为在这种情况下我们不需要使用正则表达式匹配,我们只是想匹配所述字符串。这给了我们一个列出了各种元素的列表:
R> spl
[[1]]
[1] "111" "222"
[[2]]
[1] "333"
[[3]]
[1] "444" "555" "666" "777"
[[4]]
[1] "888" "999"
下一行只是计算列表spl
lens <- sapply(spl, length)
给了我们一个长度的矢量:
R> lens
[1] 2 1 4 2
解决方案的最后一行将前两个步骤的输出插入新数据框。诀窍是重复df1$A
lens
次的每个元素;我们使用rep()
函数。我们还需要将列表spl
展开到我们使用unlist()
执行的向量中:
out <- with(df1, data.frame(A = rep(A, lens), B = unlist(spl)))
答案 1 :(得分:7)
在我对上一个问题的回答中,与第一步完全相同:
library(reshape)
x <- melt((strsplit(as.character(df1$B), "; ")))
x <- data.frame("A"=df1[x$L1,1],"B"=x$value)