R: Эквивалент Sumif от одного фрейма данных к другому

У меня есть два кадра данных, которые выглядят примерно так (они намного больше)

df1 <- data.frame(center = c("5012","5012","5025"), 
                  product = c("Apple","Grape","Apple"),
                  value = c(20,30,50))

df1:
            Center   Product     Value
    1       5012       Apple      20
    2       5012       Grape      30
    3       5025       Apple      50

df2 <- data.frame(center = c("5012","5012","5012","5012","5012","5025"),
                  profitCenter = c("A","B","C","D","A","A"),
                  product = c("Apple","Apple","Apple", "Apple","Grape","Apple"),
                  volume = c(20,30,50,70,60,80))

df2:
        Center  Profitcenter  Product   Volume
1       5012        A          Apple     20
2       5012        B          Apple     30
3       5012        C          Apple     50
4       5012        D          Apple     70
5       5012        A          Grape     60
6       5025        A          Apple     80

Я хотел получить сумму столбца «объем» из DF2 по «центру» и «продукту» в DF1. В excel я бы сделал sumif, но я изо всех сил пытаюсь понять, как правильно сделать это с R:

DF1:
            Center   Product     Value  Volume
    1       5012       Apple      20      170
    2       5012       Grape      30      60
    3       5025       Apple      50      80

В настоящее время я создаю агрегированную версию DF2 (с group_by dplyr), а затем выполняю left_join, но мне нужно сделать это еще несколько раз, и я уверен, что есть лучший способ.

С dplyr это прямое слияние и суммирование: df1 %>% left_join(df2) %>% group_by(center, product, value) %>% summarize(Volume=sum(volume))

MrFlick 11.05.2022 15:14
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Аналогично комментарию @MrFlick, но я бы предпочел, чтобы первыйsummarise работал с df2, а потом добавлял полученный столбец в df1. Но результат и производительность одинаковы. Как отметил @r2evans:

library(tidyverse)
df2 %>% 
  group_by(center, product) %>% 
  summarise(Volume=sum(volume)) %>% 
  right_join(df1,by=c("center","product"))

Или:

library(tidyverse)
df1 %>% 
  left_join(
    df2 %>% 
      group_by(center,product) %>% 
      summarise(sum(volume)),
  by=c("center","product")
  )

Или (чтобы избежать вложенности, еще раз спасибо @r2evans):

library(tidyverse)
df2 %>% 
  group_by(center, product) %>% 
  summarise(Volume=sum(volume)) %>% 
  left_join(df1,.,by=c("center","product"))

Выход:

  center product value sum(volume)
1   5012   Apple    20         170
2   5012   Grape    30          60
3   5025   Apple    50          80

Субъективно вложенные %>% кажутся более сложными. Как насчет df2 %>% group_by(center, product) %>% summarise(Volume=sum(volume)) %>% right_join(df1,by=c("center","product"))?

r2evans 11.05.2022 16:40

Совершенно верно. Я привык к left_join и вложенности. @r2evans

RobertoT 11.05.2022 20:21

(Не спорю с все, у каждого свой стиль/предпочтения. Я часто вижу этот стиль, поэтому не придираюсь к вам.) Одним из преимуществ magrittr::%>% является "избегание вложенных вызовов функций" (из magrittr.tidyverse.org), не кажется ли это странным вы считаете, что его использование теперь удобно в сфере, которую он пытается уменьшить? Конечно, вложение одного уровня, как здесь, сильно отличается от чтения calls(nested(multiple(x))). Опять же, не критично, просто любопытно и разговорчиво. Я сейчас остановлюсь :-)

r2evans 11.05.2022 20:49

Кстати, если ваше обоснование вложения в значительной степени связано с вашим предпочтением left_join, то всегда можно сделать df2 %>% group_by(center, product) %>% summarise(Volume=sum(volume)) %>% left_join(df1,.,by=c("center","product")) для того же эффекта, без вложения. Конечно, это не будет работать с базовой |> трубой, но это не вопрос или ваш ответ ...

r2evans 11.05.2022 20:50

О, спасибо за помощь @r2evans, я не знал left_join(df1,.,...). Я начну использовать эти альтернативы. И я обновлю ответ. Я ценю все эти предложения, они действительно полезны для улучшения и помогают мне избежать некоторых вредных привычек;)

RobertoT 12.05.2022 09:57

Другие вопросы по теме