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

a83*_*a83 4 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
Run Code Online (Sandbox Code Playgroud)

我想要一个这样的数据帧:

aaa 111
aaa 222
bbb 333
ccc 444
ccc 555
ccc 666
ccc 777
ddd 888
ddd 999
Run Code Online (Sandbox Code Playgroud)

我发现了一个很棒的解决方案,可以在以前的Stack Overflow问题中将类似的列表转换为数据帧.但是,我很难从具有多个条目的数据框转换它.我怎样才能做到这一点?

Rei*_*son 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)))
Run Code Online (Sandbox Code Playgroud)

这给了我们:

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
Run Code Online (Sandbox Code Playgroud)

代码在做什么?第1行:

spl <- with(df1, strsplit(as.character(B), split = "; ", fixed = TRUE))
Run Code Online (Sandbox Code Playgroud)

B使用"; "中的每个字符串拆分为要拆分的字符.我们使用fixed = TRUE(正如@Marek在评论中所建议的)来加速匹配和拆分,因为在这种情况下我们不需要使用正则表达式进行匹配,我们只想匹配所声明的字符串.这给了我们一个列出了各种元素的列表:

R> spl
[[1]]
[1] "111" "222"

[[2]]
[1] "333"

[[3]]
[1] "444" "555" "666" "777"

[[4]]
[1] "888" "999"
Run Code Online (Sandbox Code Playgroud)

下一行只计算列表的每个组件中有多少元素 spl

lens <- sapply(spl, length)
Run Code Online (Sandbox Code Playgroud)

这给了我们一个长度的向量:

R> lens
[1] 2 1 4 2
Run Code Online (Sandbox Code Playgroud)

解决方案的最后一行将前两个步骤的输出插入新数据帧.诀窍是重复每个元素df1$A lens的次数; 我们使用该rep()功能.我们还需要将列表展开spl到我们使用的向量中unlist():

out <- with(df1, data.frame(A = rep(A, lens), B = unlist(spl)))
Run Code Online (Sandbox Code Playgroud)


Bra*_*sen 7

在我对上一个问题的回答中,与第一步完全相同:

library(reshape)
x <- melt((strsplit(as.character(df1$B), "; ")))
x <- data.frame("A"=df1[x$L1,1],"B"=x$value)
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,`strsplit`的`fixed = TRUE`参数加速执行. (2认同)