2016-12-24 6 views
0

私はRで簡単な方法を探していましたが、見つけられなかったので、ここに投稿しています。Rで2つのデータフレームの違いを取るR

のは、私は、次のデータフレーム

state1  score1  state2 score2 
    A   1   A   3 
    A   2   B   13 
    A   1   C   5 
    B   10   A   1 
    B   5   B   0 
    B   3   C   0 
    C   2   A   5 
    C   0   B   6 
    C   1   C   3 

と第二のデータフレームを持っていると仮定しましょう

state1  state2 score 
    A   A   0 
    A   B   -1 
    A   C   3 
    B   A   2 
    B   B   1 
    B   C   1 
    C   A   2 
    C   B   2 
    C   C   1 

はのは、最初のデータフレーム、DF1を呼ぶことにしましょう、と第二のマージン、DF2を呼び出しています。

同じ(state1、state2)のペアを持つdf1、df2を見てください。 一致するペアごとに、df1のscore1からdf2のスコアを減算してnewscore1とし、df2のscore2からdf2のスコアを減算してnewscore2とします。この場合、以下の出力が望ましいでしょう。

state1 newscore1 state2 newscore2 
    A   1   A   3 
    A   3   B   14 
    A   -2   C   2 
    B   8   A   -1 
    B   4   B   -1 
    B   2   C   -1 
    C   0   A   3 
    C   -2   B   4 
    C   0   C   2 

1/2ライナーの解決策はありますか? そうでなければ、私はしなければならない

1)state1、state2がdf1と一致するようにdf2を並べ替える(この場合、df1の行1はすでにdf2の行1と一致するので何もする必要はない、DF1の行2は、すでに)DF2にし、その上の行2で

2と一致する)DF1 $ SCORE1-DF2の$スコア、DF1 $ score2-DF2の$スコア

答えて

3

を使用した1ライナー。

(他の解決方法が示唆しているように)結合を行ってから、参照更新演算子(:=)を使用して1つの手順で新しい列を追加します。

df1[ df2, on = c("state1","state2"), `:=`(newscore1 = score1 - score, newscore2 = score2 - score)] 
df1 
# state1 score1 state2 score2 newscore1 newscore2 
# 1:  A  1  A  3   1   3 
# 2:  A  2  B  13   3  14 
# 3:  A  1  C  5  -2   2 
# 4:  B  10  A  1   8  -1 
# 5:  B  5  B  0   4  -1 
# 6:  B  3  C  0   2  -1 
# 7:  C  2  A  5   0   3 
# 8:  C  0  B  6  -2   4 
# 9:  C  1  C  3   0   2 
1

にこの意志を行うためのクリーンな方法をCBIND結合操作をしてください。私はdplyrが好きです。例:ここでは

state1 <- gl(3, k=3, labels=c("A", "B", "C")) 
score1 <- sample(1:10, size = 9, replace = TRUE) 
state2 <- gl(3, k=1, length=9, labels=c("A", "B", "C")) 
score2 <- sample(1:10, size = 9, replace = TRUE) 
df1 <- data.frame(state1, score1, state2, score2) 

は、その最初のデータフレームです:

> df1 
    state1 score1 state2 score2 
1  A  3  A  6 
2  A  8  B  2 
3  A  3  C  6 
4  B  2  A  8 
5  B  3  B  10 
6  B  3  C  6 
7  C  7  A  2 
8  C  9  B  5 
9  C  6  C  10 

score <- sample(-5:5, size = 9, replace = TRUE) 
df2 <- data.frame(state1, state2, score) 

そして、ここでのセカンド:

> df2 
    state1 state2 score 
1  A  A -1 
2  A  B  1 
3  A  C -2 
4  B  A  5 
5  B  B  5 
6  B  C  5 
7  C  A  0 
8  C  B -1 
9  C  C -3 

combined_df <- df1 %>% 
    # line df1 and df2 up by state1 and state2, and combine them 
    full_join(df2, by=c("state1", "state2")) %>% 
    # calculate the new columns you need 
    mutate(newscore1 = score1 - score, newscore2 = score2 - score) %>% 
    # drop the extra columns 
    select(state1, newscore1, state2, newscore2) 

> combined_df 
    state1 newscore1 state2 newscore2 
1  A   4  A   7 
2  A   7  B   1 
3  A   5  C   8 
4  B  -3  A   3 
5  B  -2  B   5 
6  B  -2  C   1 
7  C   7  A   2 
8  C  10  B   6 
9  C   9  C  13 
+0

「サンプル」を使用する場合は、サンプルを再現可能にするために 'set.seed()'も使用する必要があります。 – SymbolixAU

2

は、単に2をマージし、列ごとに減算:

dfm <- merge(df1, df2, by=c("state1", "state2")) 
dfm$newscore1 <- dfm$score1 - dfm$score 
dfm$newscore2 <- dfm$score2 - dfm$score 

dfm <- dfm[c("state1", "newscore1", "state2", "newscore2")] 
関連する問題