Как использовать group_by и суммировать несколько подмножеств из одного data.frame? - PullRequest
0 голосов
/ 22 апреля 2019

Я получил следующие data.frame:

     country1 value1 country2 value2 country3 value3
2375    Other     43   Jordan     30       NA     NA
2366    Other     89   Turkey     29       NA     NA
4904   Turkey     50     Iraq     28       NA     NA
4786   Jordan     20   Turkey     25       NA     NA
5816   Jordan      7   Turkey     10       NA     NA
2365  Lebanon     18    Other      9       NA     NA

, где значение1, значение2 и значение3 не зависят друг от друга.

Я хочу в основном получить таблицу, обобщающую каждую страну и ее совокупную стоимость:

  country total_value
1    Iraq         294
2  Jordan         993
3 Lebanon        1632
4   Other         167
5  Turkey         942

Я попробовал «грубый» подход, раздельно подставив три раза исходный data.frame, связав получившиеся подмножества, а затем сгруппировав и суммировав с помощью dplyr:

subset1 <- my_data %>% select(country = country1, value= value1)

subset2 <- my_data %>% select(country = country2, value = value2)

subset3 <- my_data %>% select(country = country3, value = value3)

subset_all <- bind_rows(subset1, subset2, subset3)

my_result <- subset_all %>% group_by(country) %>% summarise(total_value = sum(value, na.rm=TRUE)) 

Я бы хотел получить тот же результат более «изящным» способом. Я пробовал подходы, использующие либо «собрать» из dplyr, либо «расплавить» из data.table, но по какой-то причине я получаю немного более высокие цифры (полагаю, некоторые строки дублируются). Любое предложение о том, как улучшить этот код?). Спасибо за вашу помощь!

Ответы [ 2 ]

0 голосов
/ 22 апреля 2019

Как насчет этого?

result <- data.frame(
  country = as.vector(t(keep(df, str_detect(names(df),  "country")))),
  value = as.numeric(as.vector(t(keep(df, str_detect(names(df),  "value")))))
) %>%
  na.omit() %>%
  group_by(country) %>%
  summarise(res = sum(value, na.rm = TRUE))

result

# A tibble: 5 x 2
  country   res
  <fct>   <dbl>
1 Iraq       28
2 Jordan     57
3 Lebanon    18
4 Other     141
5 Turkey    114
  1. Определение имен, которые содержат «страну» или «значение».
  2. ИСПОЛЬЗУЙТЕ функцию keep из пакета purrr, чтобы сохранить только те столбцы, которые TRUE для этих условий.
  3. Создать вектор и создать новый фрейм данных
  4. Избавиться от значений
  5. group_by и summarise как хотите.

Я думаю, что функции str_detect и keep - хороший способ, поскольку они обеспечивают гибкость, если ваш фрейм данных помечен правильно.

0 голосов
/ 22 апреля 2019

Вот более динамичный способ получить ваши подмножества, Предполагая, что вы хотите разделить КАЖДЫЕ 2 КОЛОННЫ , то есть

df <- unname(df)

do.call(rbind, split.default(df, rep(seq(ncol(df)/2), each = 2))) %>% 
   group_by(country) %>% 
   summarise(res = sum(value)) %>% 
   filter(!is.na(country))

, что дает,

# A tibble: 5 x 2
  country   res
  <fct>   <int>
1 Jordan     57
2 Lebanon    18
3 Other     141
4 Turkey    114
5 Iraq       28
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...