Сравнение значений в двух данных и возвращение различий - PullRequest
1 голос
/ 10 октября 2019

Я хотел бы сравнить два фрейма данных, чтобы найти значения дельты по «Группе». Существуют случаи, когда первый фрейм данных может иметь «Группу», которой нет у другого. В этих случаях результат должен отражать показанное значение.

df1 <- data.frame(Group = c("A","B","C","D","E","F","G","H"),
              Month.1 = c(10,15,30,24,16,33,27,19),
              Month.2 = c(20,37,12,31,26,22,31,20))

df2 <- data.frame(Group = c("A","B","C","D","E","F","G"),
              Month.1 = c(12,25,34,24,21,30,22),
              Month.2 = c(28,40,36,32,26,17,25))

Я не совсем уверен, как решить эту проблему. Я исследовал использование setdiff, но он возвращает только исходные значения, а не разницу.

Результат должен быть следующим:

result <- data.frame(Group = c("A","B","C","D","E","F","G","H"),
                 Month.1 = c(2,10,4,0,5,-3,-5,19),
                 Month.2 = c(8,3,24,1,0,-5,-6,20))

1 Ответ

2 голосов
/ 10 октября 2019

Мы можем сделать full_join на df1 и df2, group_by Group и взять разницу между значениями. (Спасибо @Onyambu за предложение этого подхода)

library(dplyr)

full_join(df1, df2) %>%
   group_by(Group) %>%
   summarise_all(~if(n() > 1) diff(.) else .)

#  Group Month.1 Month.2
#  <chr>   <dbl>   <dbl>
#1 A           2       8
#2 B          10       3
#3 C           4      24
#4 D           0       1
#5 E           5       0
#6 F          -3      -5
#7 G          -5      -6
#8 H          19      20

, который в базе R равен

aggregate(.~Group, merge(df1, df2, all = TRUE), function(x) 
          if(length(x) > 1) diff(x) else x)
...