2013-04-15 9 views
11

サイト内に3種類のデータフレーム(行:サイト、列:種名)があります。行番号は同じですが、すべての種が3つのデータフレームすべてにあるわけではないので、列番号は異なります。私はそれらを1つのデータフレームに統合し、同種の豊富なものを集約したいと思います。例えば:私が持っていると思いますどのような同じ列の値を集計したdata.framesをR

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 

私はマージと一緒に作業しなければならないだろうと思っていますが、これまでの試みでは私が望むものを得ることができませんでした。

何か助けていただければ幸いです。

私は plyr使用したい
+0

おそらく 'aggregate'は' merge'よりも優れていますか? –

答えて

18

「は、このようなのrbind.fill次のように、そして、plyr'sddplyとの集計を

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 

を:

ddply(pp, .(names), function(x) colSums(x[,-1], na.rm = TRUE)) 
# names 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 
+3

私は念頭に置いて解決策を持っていましたが、それはこのエレガントではないと約束します。 +1 –

+0

は完璧に機能しました。 unfortunatellyは投票できません:( – eugenego

+0

@ eugenego質問に最もよく答える解決策の横にチェックマークを付けることができます。 –

2

アルンの答えの代わりに: 作成 'テンプレート' を必要なすべての列を含む配列

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 
01このようなすべての拡張データ・フレームを合計すると

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 

はその後、拡大データフレームを作成します

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 

のようなあなたのデータフレームのそれぞれに与えられました。不器用だがシンプル。

6

もう1つの方法は、を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関数は、複数のセルが生成される変数で使用されます。

もちろん、ループまたは*適用機能を使用して、コードをより一般的なケースに拡張することができます。

5

利用可能なオプションに加えて、ここでは2つのベースが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 

番目のオプション:長期にセミワイドワイド

には、概念的には、これはマキシムに似ています。 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 
関連する問題