Выполняйте вычисления в именованных группах кадров данных в списке кадров данных, уменьшайте список, возвращайте список в tidyverse, R

#r #dplyr #tidyverse

Вопрос:

Я хотел бы начать со списка из 9 именованных фреймов данных (например, transport_list ниже), уменьшить их (полное соединение) до 3 фреймов данных на основе соответствия имен префиксов фреймов данных (например, buses_, скоростные поезда, двухциклы и т. Д.).

Затем рассчитайте среднее значение для каждого города в каждом из 3 — х фреймов данных- в основном за период с 2017 по 2019 год.

Чтобы, наконец, получить список (например, desired_output_list) из 3 именованных фреймов данных (автобусы, поезда, двухциклы), каждый из которых содержит следующие столбцы (город, значение)

Как я могу это сделать с помощью tidyverse/dplyr?

ПРИМЕЧАНИЕ: Имена префиксов могут состоять из одного слова, например «автобусы«, или двух слов с пробелом, например «скоростной поезд«, или двух слов с дефисом между «двухцикл_*».

NB2: Этот шаблон суффикса постоянен во всех кадрах данных в списке с *_2017 по *_2019, т. е. в годах, с которых рассчитываются средние значения.

NB3 В реальном наборе данных у меня есть 9 именованных фреймов данных, на самом деле 216. А также более 3 лет 2005:2019.

 transport_list <- list(buses_2017 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(34, 41, 50, 48)),
                       
                       buses_2018 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(37, 45, 60, 38)),
                       
                       buses_2019 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(41, 46, 58, 35)),
                       
                       "speed trains_2017" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(48, 50, 41, 34)),
                       
                       "speed trains_2018" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(38, 45, 12, 15)),
                       
                       "speed trains_2019" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(50, 48, 51, 22)),

                       "bi-cycles_2017" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(148, 150, 141, 134)),
                       
                       "bi-cycles_2018" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(380, 450, 120, 150)),
                       
                       "bi-cycles_2019" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(500, 480, 510, 220  )))

### Starting from a list of 9 named dataframes, reduce them (fulljoin) to 3 dataframes based on matching dataframe prefix names (e.g. buses_*, trains_*, bi-cycles_* etc). Then calculate the mean value for each city within each of the 3 dataframes. To finally end up with a list of 3 named dataframes (buses, trains, bi-cycles) each of which has the following columns (city, value_mean)

transport_list %>%
  reduce(full_join) %>%  
  group_by(city) %>% 
  summarise(mean(value)) %>% 
  arrange(city)

####### Desired output should look like this list ##########

desired_output_list <- list(buses = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                               mean_value = c(37.333, 44, 56, 43.667)),
                       
                       trains = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                mean_value = c(45.333, 47.667, 34.667, 23.667)),
                       
                       "bi-cycles" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   mean_value = c(342.667, 360, 257, 168)))
 

Ответ №1:

Вы можете разделить список по их имени и использовать map для применения одной и той же функции к каждому списку.

 library(tidyverse)

split(transport_list, sub('_\d ', '', names(transport_list))) %>%
  map(~.x %>%
        reduce(full_join) %>%  
        group_by(city) %>% 
        summarise(value = mean(value)) %>% 
        arrange(city))

#
 #r #dplyr #tidyverse



Вопрос:

Я хотел бы начать со списка из 9 именованных фреймов данных (например, transport_list ниже), уменьшить их (полное соединение) до 3 фреймов данных на основе соответствия имен префиксов фреймов данных (например, buses_, скоростные поезда, двухциклы и т. Д.). Затем рассчитайте среднее значение для каждого города в каждом из 3 - х фреймов данных- в основном за период с 2017 по 2019 год. Чтобы, наконец, получить список (например, desired_output_list) из 3 именованных фреймов данных (автобусы, поезда, двухциклы), каждый из которых содержит следующие столбцы (город, значение) Как я могу это сделать с помощью tidyverse/dplyr? ПРИМЕЧАНИЕ: Имена префиксов могут состоять из одного слова, например "автобусы", или двух слов с пробелом, например "скоростной поезд", или двух слов с дефисом между "двухцикл_*". NB2: Этот шаблон суффикса постоянен во всех кадрах данных в списке с *_2017 по *_2019, т. е. в годах, с которых рассчитываются средние значения. NB3 В реальном наборе данных у меня есть 9 именованных фреймов данных, на самом деле 216. А также более 3 лет 2005:2019.
 transport_list <- list(buses_2017 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(34, 41, 50, 48)),
                       
                       buses_2018 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(37, 45, 60, 38)),
                       
                       buses_2019 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(41, 46, 58, 35)),
                       
                       "speed trains_2017" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(48, 50, 41, 34)),
                       
                       "speed trains_2018" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(38, 45, 12, 15)),
                       
                       "speed trains_2019" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(50, 48, 51, 22)),

                       "bi-cycles_2017" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(148, 150, 141, 134)),
                       
                       "bi-cycles_2018" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(380, 450, 120, 150)),
                       
                       "bi-cycles_2019" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(500, 480, 510, 220  )))

### Starting from a list of 9 named dataframes, reduce them (fulljoin) to 3 dataframes based on matching dataframe prefix names (e.g. buses_*, trains_*, bi-cycles_* etc). Then calculate the mean value for each city within each of the 3 dataframes. To finally end up with a list of 3 named dataframes (buses, trains, bi-cycles) each of which has the following columns (city, value_mean)

transport_list %>%
  reduce(full_join) %>%  
  group_by(city) %>% 
  summarise(mean(value)) %>% 
  arrange(city)

####### Desired output should look like this list ##########

desired_output_list <- list(buses = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                               mean_value = c(37.333, 44, 56, 43.667)),
                       
                       trains = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                mean_value = c(45.333, 47.667, 34.667, 23.667)),
                       
                       "bi-cycles" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   mean_value = c(342.667, 360, 257, 168)))
 

Ответ №1:

Вы можете разделить список по их имени и использовать map для применения одной и той же функции к каждому списку.

bi-cycles`
# A tibble: 4 x 2
# city value
# <chr> <dbl>
#1 Cambridge 343.
#2 Glasgow 168
#3 London 360
#4 Oxford 257

#$buses
# A tibble: 4 x 2
# city value
# <chr> <dbl>
#1 Cambridge 37.3
#2 Glasgow 40.3
#3 London 44
#4 Oxford 56

#

#r #dplyr #tidyverse

Вопрос:

Я хотел бы начать со списка из 9 именованных фреймов данных (например, transport_list ниже), уменьшить их (полное соединение) до 3 фреймов данных на основе соответствия имен префиксов фреймов данных (например, buses_, скоростные поезда, двухциклы и т. Д.).

Затем рассчитайте среднее значение для каждого города в каждом из 3 - х фреймов данных- в основном за период с 2017 по 2019 год.

Чтобы, наконец, получить список (например, desired_output_list) из 3 именованных фреймов данных (автобусы, поезда, двухциклы), каждый из которых содержит следующие столбцы (город, значение)

Как я могу это сделать с помощью tidyverse/dplyr?

ПРИМЕЧАНИЕ: Имена префиксов могут состоять из одного слова, например "автобусы", или двух слов с пробелом, например "скоростной поезд", или двух слов с дефисом между "двухцикл_*".

NB2: Этот шаблон суффикса постоянен во всех кадрах данных в списке с *_2017 по *_2019, т. е. в годах, с которых рассчитываются средние значения.

NB3 В реальном наборе данных у меня есть 9 именованных фреймов данных, на самом деле 216. А также более 3 лет 2005:2019.

 transport_list <- list(buses_2017 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(34, 41, 50, 48)),
                       
                       buses_2018 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(37, 45, 60, 38)),
                       
                       buses_2019 = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                value = c(41, 46, 58, 35)),
                       
                       "speed trains_2017" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(48, 50, 41, 34)),
                       
                       "speed trains_2018" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(38, 45, 12, 15)),
                       
                       "speed trains_2019" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                 value = c(50, 48, 51, 22)),

                       "bi-cycles_2017" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(148, 150, 141, 134)),
                       
                       "bi-cycles_2018" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(380, 450, 120, 150)),
                       
                       "bi-cycles_2019" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   value = c(500, 480, 510, 220  )))

### Starting from a list of 9 named dataframes, reduce them (fulljoin) to 3 dataframes based on matching dataframe prefix names (e.g. buses_*, trains_*, bi-cycles_* etc). Then calculate the mean value for each city within each of the 3 dataframes. To finally end up with a list of 3 named dataframes (buses, trains, bi-cycles) each of which has the following columns (city, value_mean)

transport_list %>%
  reduce(full_join) %>%  
  group_by(city) %>% 
  summarise(mean(value)) %>% 
  arrange(city)

####### Desired output should look like this list ##########

desired_output_list <- list(buses = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                               mean_value = c(37.333, 44, 56, 43.667)),
                       
                       trains = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                mean_value = c(45.333, 47.667, 34.667, 23.667)),
                       
                       "bi-cycles" = data.frame(city = c("Cambridge", "London", "Oxford", "Glasgow"),
                                                   mean_value = c(342.667, 360, 257, 168)))
 

Ответ №1:

Вы можете разделить список по их имени и использовать map для применения одной и той же функции к каждому списку.

speed trains`
# A tibble: 4 x 2
# city value
# <chr> <dbl>
#1 Cambridge 45.3
#2 Glasgow 23.7
#3 London 47.7
#4 Oxford 34.7


Это можно перевести в базе R как —

 lapply(split(transport_list, sub('_\d ', '', names(transport_list))), function(x) {
  aggregate(value ~ city, Reduce(function(x, y) merge(x, y, all = TRUE), x), mean)
})