R数据转换

4

我有一个看起来像这样的R数据框:

z = as.data.frame(list(Col1=c("a","c","e","g"),Col2=c("b","d","f","h"),Col3=c("1,2,5","3,5,7","9,8","1")))
> z
  Col1 Col2  Col3
1    a    b 1,2,5
2    c    d 3,5,7
3    e    f   9,8
4    g    h     1

第三列是一个由逗号分隔的文本列。我希望将其转换为以下数据框:

a    b    1
a    b    2
a    b    5
c    d    3
c    d    5
c    d    7
e    f    9 
e    f    8
g    h    1

有人能建议一种使用apply完成这个任务的方法吗?我已经接近成功,但还不够完美。如果有更高效的方法也希望得到建议...

> apply(z,1,function(a){ids=strsplit(as.character(a[3]),",")[[1]];out<-c();for(id in ids){out<-rbind(out,c(a[1:2],id))};return(out)})
[[1]]
     Col1 Col2    
[1,] "a"  "b"  "1"
[2,] "a"  "b"  "2"
[3,] "a"  "b"  "5"

[[2]]
     Col1 Col2    
[1,] "c"  "d"  "3"
[2,] "c"  "d"  "5"
[3,] "c"  "d"  "7"

[[3]]
     Col1 Col2    
[1,] "e"  "f"  "9"
[2,] "e"  "f"  "8"

[[4]]
     Col1 Col2    
[1,] "g"  "h"  "1"

我还要注意一下,我在一个更大的真实数据集上测试了这里提出的两个解决方案,也许并不令人惊讶的是,执行时间几乎相同。如果对任何人有用的话... - Andrew
2个回答

5
您可以使用ddply
library(plyr)
ddply(z, c("Col1", "Col2"), summarize, 
  Col3=strsplit(as.character(Col3),",")[[1]]
)

3

使用 reshapereshape2

require(reshape2)
merge(cbind(z[,-3], L1=rownames(z)), melt(strsplit(as.character(z$Col3),",")))

提供

  L1 Col1 Col2 value
1  1    a    b     1
2  1    a    b     2
3  1    a    b     5
4  2    c    d     3
5  2    c    d     5
6  2    c    d     7
7  3    e    f     9
8  3    e    f     8
9  4    g    h     1

很好!两个答案都完美地解决了问题,所以不可能选择一个“更好”的答案。最终选择了这个答案,因为它指向了merge函数,这似乎是一个我也需要学习的不错的通用工具... - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接