Получить общее среднее значение для переменных, вложенных в список списков списков - PullRequest
0 голосов
/ 09 мая 2019

Примите список списков, которые могут быть, например, представлять рынки за периоды времени. У нас есть шесть периодов и в каждом периоде одни и те же три рынка. Для каждого рынка может быть много переменных. Здесь нас интересуют profit и sales. Мы хотим рассчитать среднее значение для каждого за все периоды и для всех рынков. Вот набор данных игрушек:

periods <- list()
markets <- list()

set.seed(11)
for (i in seq(1:6)) {
    for (j in seq(1:3)) {
        markets[[j]] <- list(profit =  sample(1:100, 1), sales =  sample(1:10, 1))
        }
    periods[[i]] <- markets
}

Вот некоторые фактические данные:

list(list(list(profit = 28L, sales = 1L), list(profit = 52L, 
    sales = 1L), list(profit = 7L, sales = 10L)), list(list(profit = 9L, 
    sales = 3L), list(profit = 89L, sales = 2L), list(profit = 18L, 
    sales = 5L)), list(list(profit = 91L, sales = 9L), list(profit = 74L, 
    sales = 6L), list(profit = 49L, sales = 4L)), list(list(profit = 16L, 
    sales = 5L), list(profit = 21L, sales = 7L), list(profit = 37L, 
    sales = 4L)), list(list(profit = 7L, sales = 5L), list(profit = 40L, 
    sales = 1L), list(profit = 13L, sales = 4L)), list(list(profit = 51L, 
    sales = 4L), list(profit = 42L, sales = 3L), list(profit = 82L, 
    sales = 7L)))

Ожидаемый результат:

profit == 40,33
sales == 4,5

Теперь я могу добиться этого, используя цикл. Но мне бы очень хотелось увидеть более элегантное решение. Предпочтительно с tidyverse. Для простого списка значений я мог бы использовать что-то вроде periods %>% map('sales') %>% unlist() %>% mean(). Тем не менее, я потерпел неудачу в этом более сложном случае.

Ответы [ 3 ]

2 голосов
/ 09 мая 2019

Вы можете попробовать

df %>% 
   flatten() %>% 
   flatten() %>% 
   tibble(a=names(.), b=unlist(.)) %>% 
   group_by(a) %>% 
   summarise(Mean=mean(b))
# A tibble: 2 x 2
  a       Mean
  <chr>  <dbl>
1 profit  40.3
2 sales    4.5

Или просто запустить

df %>% 
   reduce(bind_rows) %>% 
   summarise_all(mean)
# A tibble: 1 x 2
  profit sales
   <dbl> <dbl>
1   40.3   4.5
1 голос
/ 09 мая 2019

Вы можете красиво создать матрицу после распечатки и подвести итог.

summary(matrix(unlist(periods), , 2, by=TRUE))
#       V1              V2       
# Min.   : 3.00   Min.   : 1.00  
# 1st Qu.:29.00   1st Qu.: 2.25  
# Median :46.50   Median : 4.00  
# Mean   :47.67   Mean   : 5.00  
# 3rd Qu.:67.50   3rd Qu.: 7.00  
# Max.   :89.00   Max.   :10.00  
summary(matrix(unlist(markets), , 2, by=TRUE))
#       V1              V2   
# Min.   :29.00   Min.   :4  
# 1st Qu.:44.50   1st Qu.:5  
# Median :60.00   Median :6  
# Mean   :56.33   Mean   :6  
# 3rd Qu.:70.00   3rd Qu.:7  
# Max.   :80.00   Max.   :8  

summary(matrix(unlist(list(periods, markets)), , 2, by=TRUE))
#       V1             V2        
# Min.   : 3.0   Min.   : 1.000  
# 1st Qu.:29.0   1st Qu.: 3.000  
# Median :48.0   Median : 4.000  
# Mean   :48.9   Mean   : 5.143  
# 3rd Qu.:70.0   3rd Qu.: 7.000  
# Max.   :89.0   Max.   :10.000 
0 голосов
/ 09 мая 2019

Мы могли бы использовать map для циклического перебора всех списков в periods и выбора столбцов "profit" и "sales" по отдельности, а затем взять mean над ним.

library(tidyverse)

tibble(
  profit = map(periods, ~pluck(., 1) %>% flatten_dbl) %>% flatten_dbl %>% mean, 
  sales = map(periods, ~pluck(., 2) %>% flatten_dbl) %>% flatten_dbl %>% mean
 )

# A tibble: 1 x 2
#  profit sales
#   <dbl> <dbl>
#1   40.3   4.5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...