合并data.frames汇总R中相同列的值

时间:2013-04-15 15:18:35

标签: r merge dataframe aggregate

我有3个数据框(行:网站,列:物种名称),这些数据框内的物种丰富度。行号相同,但列号不同,因为并非所有物种都在所有三个数据帧中。我想将它们合并到一个数据框架中,总结出相同物种的丰富程度。例如:

data.frame1

       Sp1  Sp2  Sp3  Sp4
site1   1    2    3    1
site2   0    2    0    1
site3   1    1    1    1

data.frame2

       Sp1  Sp2  Sp4
 site1  0    1    2
 site2  1    2    0
 site3  1    1    1

data.frame3

       Sp1  Sp2  Sp5  Sp6
 site1  0    1    1    1     
 site2  1    1    1    5
 site3  2    0    0    0

我想拥有的是:

       Sp1  Sp2  Sp3  Sp4  Sp5  Sp6
 site1  1    4    3    3    1    1
 site2  2    5    0    1    1    5
 site3  4    2    1    2    0    0

我想我必须使用合并,但到目前为止,我的尝试未能得到我想要的东西。

感谢任何帮助。

4 个答案:

答案 0 :(得分:21)

我会像这样使用plyr的{​​{1}}:

rbind.fill

然后,与pp <- cbind(names=c(rownames(df1), rownames(df2), rownames(df3)), rbind.fill(list(df1, df2, df3))) # names Sp1 Sp2 Sp3 Sp4 Sp5 Sp6 # 1 site1 1 2 3 1 NA NA # 2 site2 0 2 0 1 NA NA # 3 site3 1 1 1 1 NA NA # 4 site1 0 1 NA 2 NA NA # 5 site2 1 2 NA 0 NA NA # 6 site3 1 1 NA 1 NA NA # 7 site1 0 1 NA NA 1 1 # 8 site2 1 1 NA NA 1 5 # 9 site3 2 0 NA NA 0 0 plyr's合并如下:

ddply

答案 1 :(得分:7)

另一种方法是使用melt/cast中的reshape2。这是一个简单的例子:

df1 <- read.table(header=T, text="
    Sp1  Sp2  Sp3  Sp4
    site1   1    2    3    1
    site2   0    2    0    1
    site3   1    1    1    1")

df2 <- read.table(header=T, text="
       Sp1  Sp2  Sp4
 site1  0    1    2
 site2  1    2    0
 site3  1    1    1")

df3 <- read.table(header=T, text="
       Sp1  Sp2  Sp5  Sp6
 site1  0    1    1    1     
 site2  1    1    1    5
 site3  2    0    0    0")

df1$site <- rownames(df1)
df2$site <- rownames(df2)
df3$site <- rownames(df3)

DF <- rbind(melt(df1,id="site"),melt(df2,id="site"),melt(df3,id="site"))
dcast(data=DF,formula=site ~ variable,fun.aggregate=sum)

   site Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
1 site1   1   4   3   3   1   1
2 site2   2   5   0   1   1   5
3 site3   4   2   1   2   0   0

简而言之,我们使用站点指定作为附加变量,并将每个数据帧转换为长格式,然后将它们连接成单个数据帧。后者包含长格式的所有值。使用dcast,我们创建您需要的数据框,网站在行中(公式的左侧),变量在列中(公式的右侧)。 sum函数用于生成多个单元格的变量。

当然,代码可以扩展到循环或* apply函数的更一般情况。

答案 2 :(得分:5)

添加可用选项,这里还有两个坚持基础R.

第一个选项广泛聚合(排序)

temp <- cbind(df1, df2, df3)
temp
#       Sp1 Sp2 Sp3 Sp4 Sp1 Sp2 Sp4 Sp1 Sp2 Sp5 Sp6
# site1   1   2   3   1   0   1   2   0   1   1   1
# site2   0   2   0   1   1   2   0   1   1   1   5
# site3   1   1   1   1   1   1   1   2   0   0   0
sapply(unique(colnames(temp)), 
       function(x) rowSums(temp[, colnames(temp) == x, drop = FALSE]))
#       Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
# site1   1   4   3   3   1   1
# site2   2   5   0   1   1   5
# site3   4   2   1   2   0   0

第二个选项半宽到长到宽

从概念上讲,这与Maxim类似。 K的答案:以长篇形式获取数据,这使得操作更容易:

> temp1 <- t(cbind(df1, df2, df3))
> # You'll get a warning in the next step
> # Safe to ignore though...
> temp2 <- data.frame(var = rownames(temp), stack(data.frame(temp)))
Warning message:
In data.row.names(row.names, rowsi, i) :
  some row.names duplicated: 5,6,7,8,9 --> row.names NOT used
> xtabs(values ~ ind + var, temp2)
       var
ind     Sp1 Sp2 Sp3 Sp4 Sp5 Sp6
  site1   1   4   3   3   1   1
  site2   2   5   0   1   1   5
  site3   4   2   1   2   0   0

答案 3 :(得分:2)

Arun回答的另一种选择: 创建一个“模板”数组,其中包含您需要的所有列

Rgames> bbar<-data.frame('one'=rep(0,3),'two'=rep(0,3),'three'=rep(0,3))
Rgames> bbar
  one two three
1  0    0    0
2   0    0    0
3   0    0    0

然后,给出每个数据框,如

Rgames> bar1<-data.frame('one'=c(1,2,3),'two'=c(4,5,6))
Rgames> bar1
  one two
1   1   4
2   2   5
3   3   6

创建扩展数据框:

Rgames> newbar1<-bbar
Rgames> for (jj in names(bar) )  newbar1[[jj]]<-bar[[jj]]
Rgames> newbar1
  one two three
1   1   4    0
2   2   5    0
3   3   6    0

然后对所有这些扩展数据帧求和。笨拙但很简单。