如何创建一个原始数据分隔的新数据框;并且每个类别的计数不同?

时间:2011-06-03 07:44:16

标签: r dataframe

我有一张格式如下的表格。

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问题中将类似的列表转换为数据帧。但是,我很难从具有多个条目的数据框转换它。我怎么能这样做?

2 个答案:

答案 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)