2016-02-02 11 views
8

データフレームは同じ寸法または列名を持つことが保証されていないものの、私は、効率的に2つのデータフレームのエントリを合計します。マージは実際に私がここにいるものではありません。代わりに、追加されたデータフレームのいずれかに属するすべての行と列の名前を持つ出力オブジェクトを作成したいと思います。行/列ペアは、私がした場合、出力は、それらの和 追加(マージではない!)、不等行と列を持つ2つのデータフレーム

  • を含める両方の入力データ・フレームに属する場合

    • :その出力の各位置において、Iは、計算された値は、次のロジックを使用します行/列ペアは、私は、行/列ペアは、I出力にその位置に0を有するようにする任意の入力行列に属していない場合、出力
    • にその値を含めるだけ一つの入力データ・フレームに属します。

    例として、次の入力データフレームを考慮してください。

    df1 = data.frame(x = c(1,2,3), y = c(4,5,6)) 
    rownames(df1) = c("a", "b", "c") 
    df2 = data.frame(x = c(7,8), z = c(9,10), w = c(2, 3)) 
    rownames(df2) = c("a", "d") 
    > df1 
        x y 
    a 1 4 
    b 2 5 
    c 3 6 
    > df2 
        x z w 
    a 7 9 2 
    d 8 10 3 
    

    は私が最終的な結果は、私がこれまで何をやったか

    > df2 
        x y z w 
    a 8 4 9 2 
    b 2 5 0 0 
    c 3 6 0 0 
    d 8 0 10 3 
    

    になりたい -

    dplyrのbind_rows/bind_colsは次のようにスローする可能性があります。 "エラー:互換性のない行数(3、2が必要です)"

    は私が「マージ」は私の目的のために働いていない列名を、重複しているのどちらか - 何らかの理由でDF空を返します。

    (all.rows <- unique(c(row.names(df1), row.names(df2)))) 
    # [1] "a" "b" "c" "d" 
    (all.cols <- unique(c(names(df1), names(df2)))) 
    # [1] "x" "y" "z" "w" 
    

    は、その後、私はすべて0に初期化マトリックスデータを(それらの行や列名を持つ出力マトリックスを作成します:

  • 答えて

    4

    あなたはいくつかの追加いじるとゼロに合計し、NAの変換の世話をする、その後、rownamesにマージできように思える:

    library(dplyr) 
    
    df.new = df1 %>% add_rownames %>% 
        full_join(df2 %>% add_rownames, by="rowname") %>% 
        mutate_each(funs(replace(., which(is.na(.)), 0))) %>% 
        mutate(x = x.x + x.y) %>% 
        select(rowname,x,y,z,w) 
    

    それとも、@ DavidArenburgとはるかにエレガントかつ拡張可能です解決策:

    df.new = df1 %>% add_rownames %>% 
        full_join(df2 %>% add_rownames) %>% 
        group_by(rowname) %>% 
        summarise_each(funs(sum(., na.rm = TRUE))) 
    
    df.new 
    
        rowname  x  y  z  w 
    1  a  8  4  9  2 
    2  b  2  5  0  0 
    3  c  3  6  0  0 
    4  d  8  0 10  3 
    
    +0

    @DavidArenburgは、私が必要としていたよりもはるかに複雑なものにしていたので、本当にクレジットに値します。 – eipi10

    2

    まず、私は新しいエンティティのすべての行と列の名前をつかむだろう)、そのマトリックスの関連部分にdf1df2を加える。

    out <- matrix(0, nrow=length(all.rows), ncol=length(all.cols)) 
    rownames(out) <- all.rows 
    colnames(out) <- all.cols 
    out[row.names(df1),names(df1)] <- unlist(df1) 
    out[row.names(df2),names(df2)] <- out[row.names(df2),names(df2)] + unlist(df2) 
    out 
    # x y z w 
    # a 8 4 9 2 
    # b 2 5 0 0 
    # c 3 6 0 0 
    # d 8 0 10 3 
    
    +1

    ありがとう!私はこのソリューションをeipi10のほうが好きです。これは名前を変更する必要はないので、私は動的に行う必要があります。私は通常dplyrを好むが、この解決策はかなり意味がある。 –

    3

    これは、単純な集計、共通のカラム名(+行名)上の単純なマージのいくつかの種類のように思えると、これは私がタックだろうかですルこの

    library(data.table) 
    merge(setDT(df1, keep.rownames = TRUE), # Convert to data.table + keep rows 
         setDT(df2, keep.rownames = TRUE), # Convert to data.table + keep rows 
         by = intersect(names(df1), names(df2)), # merge on common column names 
         all = TRUE)[, lapply(.SD, sum, na.rm = TRUE), by = rn] # Sum all columns by group     
    # rn x y z w 
    # 1: a 8 4 9 2 
    # 2: b 2 5 0 0 
    # 3: c 3 6 0 0 
    # 4: d 8 0 10 3 
    

    溶融/積み重ねられたデータフレームにxtabsを使用して

    df1$rn <- row.names(df1) 
    df2$rn <- row.names(df2) 
    res <- merge(df1, df2, all = TRUE) 
    rowsum(res[setdiff(names(res), "rn")], res[, "rn"], na.rm = TRUE) 
    # x y z w 
    # a 8 4 9 2 
    # b 2 5 0 0 
    # c 3 6 0 0 
    # d 8 0 10 3 
    
    +0

    非常に気の利いた。私は 'merge'のall = TRUE引数について忘れました。 –

    +0

    'merge'はデフォルトで各データセットの名前の' intersect'ionを使用します。 'by ='を空白のままにして、同じ結果を得ることができます。 – thelatemail

    +0

    @thelatemailええ私はそれが基本のデフォルトであることを忘れてしまった。 'data.table'では、キーを設定していなければ動作しません。 –

    1

    かなりまっすぐ進むベースRのソリューションです:このため

    out <- rbind(cbind(rn=rownames(df1),stack(df1)), cbind(rn=rownames(df2),stack(df2))) 
    as.data.frame.matrix(xtabs(values ~ rn + ind, data=out)) 
    
    # x y w z 
    #a 8 4 2 9 
    #b 2 5 0 0 
    #c 3 6 0 0 
    #d 8 0 3 10 
    
    関連する問題