取R中两个数据帧之间的差异

时间:2016-12-24 17:31:43

标签: r dataframe

我一直在寻找一种简单的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)重新命令df2使state1,state2与df1匹配(在这种情况下,我不必做任何事情,因为df1中的第1行已经与df2中的第1行匹配,df1中的第2行已经匹配df2中的第2行,依此类推)

2)cbind df1 $ score1-df2 $得分,df1 $ score2-df2 $得分

3 个答案:

答案 0 :(得分:3)

使用library(data.table)的单线程。

进行连接(如其他解决方案所建议的那样),然后使用update-by-reference运算符(:=)在一步中添加新列。

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 :(得分: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")]

答案 2 :(得分:1)

最简单的方法是使用连接操作。我喜欢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