2012-01-05 2 views
1

2つのデータフレーム(foo,)に格納されている変数セット(X)を比較しようとしています。各Xは、最大10個の値がYに関連付けられたユニークな独立変数です。私はすべてのbar.Xとすべてのfoo.Xを比較したいのですが、それは共通の値であるYの値を比較することです。出力はfoo.xの軸とbar.xの長さの行列である可能性があります。私が残してきた2つのデータフレームからスコアリングマトリックスを作成する


foo <- data.frame(x= c('a', 'a', 'a', 'b', 'b', 'b'), y=c('ab', 'ac', 'ad', 'ae', 'fx', 'fy')) 
bar <- data.frame(x= c('c', 'c', 'c', 'd', 'd', 'd'), y=c('ab', 'xy', 'xz', 'xy', 'fx', 'xz')) 

EDIT:

fooとbarのこの単純な例では、CとB、Dを比較する2x2の行列を返すようにしたいでしょう他の初心者が(ループは効果がありますが、おそらく非常に最適ではない)次のコードは有効ですが、以下の2つの解決方法が有効です。特にRamnathのdata.tableの使用は、非常に大きなデータフレームを処理する場合に非常に有効です。

ストアはyの値は、stack機能

foo.list <- dlply(foo, .(x), function(x) stack(x, select = y)) 
bar.list <- dlply(bar, .(x),function(x) stack(x, select = y)) 

を使用して格納されているリストとしてデータフレームは

comparelists <- function(list1, list2) { 
    for (i in list1){ 
    for (j in list2){ 
     count <- 0 
     if (i[[1]] %in% j[[1]]) count <- count + 1 
    } 
    } 
    return count 
    } 

出力行列を書き込む積層された2つのリストにメンバシップを比較するための関数を書く

output.matrix <- matrix(1:length(foo.list), 1:length(bar.list)) 
for (i in foo.list){ 
    for (j in bar.list){ 
    output.matrix[i,j] <- comparelists(i,j) 

    } 

}

答えて

3

ここmerge

library(reshape2) 
df1 <- merge(foo, bar, by = 'y') 
dcast(df1, x.x ~ x.y, length) 

    x.x c d 
1 a 1 0 
2 b 0 1 

EDITを使用して簡単な方法です。 data.tableを使用すると、マージが高速になります。コードはこちら

foo_dt <- data.table(foo, key = 'y') 
bar_dt <- data.table(bar, key = 'y') 
df1 <- bar_dt[foo_dt, nomatch = 0] 
+0

感謝@ramnath - これは確かに非常にエレガントで簡単なソリューションです。残念ながら、この男はデータセット全体に適用するとコンピュータもクラッシュします。私は自分のデータを処理するためにPythonを使用する私のpre-R戦略に戻ると思います(私はデータを繰り返し、ファイルに結果を書き込んでコンピュータが壊れないようにします)。 capabilites。 – zach

+0

'foo'と' bar'の大きさはどれくらいありますか? – Ramnath

+0

私の編集をチェックしてください。それは 'data.table'を使用して' merge'を行いますので、非常に効率的です。これはあなたのために働くかどうか確認できますか?そのステップがボトルネックであれば、データをキャストする効率的な方法を見つけようとしています。 – Ramnath

4

これを実行するには、100の方法が必要です。ここで私に比較的簡単に感じるものです:

library(reshape2) 
foo <- data.frame(x = c('a', 'a', 'a', 'b', 'b', 'b'), 
        y = c('ab', 'ac', 'ad', 'ae', 'fx', 'fy')) 
bar <- data.frame(x = c('c', 'c', 'c', 'd', 'd', 'd'), 
        y = c('ab', 'xy', 'xz', 'xy', 'fx', 'xz')) 

# Create a function that counts the number of common elements in two groups 
nShared <- function(A, B) { 
    length(intersect(with(foo, y[x==A]), with(bar, y[x==B]))) 
} 

# Enumerate all combinations of groups in foo and bar 
(combos <- expand.grid(foo.x=unique(foo$x), bar.x=unique(bar$x))) 
# foo.x bar.x 
# 1  a  c 
# 2  b  c 
# 3  a  d 
# 4  b  d 

# Find number of elements in common among all pairs of groups 
combos$n <- mapply(nShared, A=combos$foo.x, B=combos$bar.x) 

# Reshape results into matrix form 
dcast(combos, foo.x ~ bar.x) 
# foo.x c d 
# 1  a 1 0 
# 2  b 0 1 
+0

nice!私はあなたが大きなグリッドに拡大し、重なりを数えてから再構築するのを見ます。エレガント。しかし、もしfooとbarが実際何千人ものメンバーになったらどうでしょうか?あなたの方法を変更しますか? – zach

+0

計算が本当に減速しない限り、私はそれを変更しません。しかし、私はこれが大規模なデータセットにはうまくいくはずだと思います。 –

+0

ありがとうございました。私はRで十分に新しく、交差、expand.grid、dcast、またはmapplyを使用しないようにしました - これは素早い回答であることに加えて、これは本当の助けになります! – zach

関連する問題