Ошибка в средневзвешенном значении. Почему он не может найти колонку?

#r #dplyr

Вопрос:

У меня есть фрейм данных, который выглядит так

 df <- data.frame(Region = c("Asia","Asia","Africa","Europe","Europe"),
Emp = c(120,40,10,67,110),
Sales18 = c(12310, 4510, 1140, 5310, 16435),
Sales19 = c(15670, 6730, 1605, 6120, 1755))
 

Я запускаю код, в котором я группируюсь по регионам, а затем беру среднее и средневзвешенное значение для всех столбцов «продажи» по «Emp»

 Result <- df %>% group_by(Region) %>% 
summarise(sales18 = mean(Sales18, na.rm = T),
sales19 = mean(Sales19, na.rm = T),
weightedsales18 = weighted.mean(Sales18, .data[[Emp]], na.rm = T),
weightedsales19 = weighted.mean(Sales19, .data[[Emp]], na.rm = T))
 

Однако я получаю следующую ошибку

 Error in splice(dot_call(capture_dots, frame_env = frame_env, named = named,  : 
  object 'Emp' not found
 

Не могу понять, что я делаю не так

Ответ №1:

Одним из вариантов может быть:

 library(tidyverse)
df <- data.frame(Region = c("Asia","Asia","Africa","Europe","Europe"),
                 Emp = c(120,40,10,67,110),
                 Sales18 = c(12310, 4510, 1140, 5310, 16435),
                 Sales19 = c(15670, 6730, 1605, 6120, 1755))


df %>%
  group_by(Region) %>%
  summarise(across(
    .cols = starts_with("Sales"),
    .fns = list(w_mean = ~ weighted.mean(.x, w = Emp), mean = ~ mean(.x)), 
    .names = "{.col}_{.fn}")
  )
#> # A tibble: 3 x 5
#>   Region Sales18_w_mean Sales18_mean Sales19_w_mean Sales19_mean
#>   <chr>           <dbl>        <dbl>          <dbl>        <dbl>
#> 1 Africa          1140         1140           1605         1605 
#> 2 Asia           10360         8410          13435        11200 
#> 3 Europe         12224.       10872.          3407.        3938.
 

Создано 2021-05-25 пакетом reprex (v2.0.0)

Ответ №2:

Это работает. Маскировка данных уже происходит, вам не нужно местоимение .data.

 library(tidyverse)
df <- data.frame(Region = c("Asia","Asia","Africa","Europe","Europe"),
                 Emp = c(120,40,10,67,110),
                 Sales18 = c(12310, 4510, 1140, 5310, 16435),
                 Sales19 = c(15670, 6730, 1605, 6120, 1755))

Result <- df %>% group_by(Region) %>% 
  summarise(sales18 = mean(Sales18, na.rm = T),
            sales19 = mean(Sales19, na.rm = T),
            weightedsales18 = weighted.mean(Sales18, Emp, na.rm = T),
            weightedsales19 = weighted.mean(Sales19, Emp, na.rm = T))
Result
#> # A tibble: 3 x 5
#>   Region sales18 sales19 weightedsales18 weightedsales19
#>   <chr>    <dbl>   <dbl>           <dbl>           <dbl>
#> 1 Africa   1140    1605            1140            1605 
#> 2 Asia     8410   11200           10360           13435 
#> 3 Europe  10872.   3938.          12224.           3407.
 

Создано 2021-05-25 пакетом reprex (v2.0.0)

Комментарии:

1. Большое спасибо, Клаудиу. Без местоимения .data я получал следующую ошибку: x ‘x’ и ‘w’ должны иметь одинаковую длину

2. Мои данные состоят из многих строк, и это всего лишь фиктивный df, которым я поделился, но x и w имеют одинаковую длину

3. Что ж, именно так это и должно работать. Ошибка, которую вы получаете, заключается в том, что ваш вектор веса имеет длину, отличную от вектора значений. Это проблема в данных, а не в описательном анализе выше.

Ответ №3:

Без кавычек Emp внутри [[ указывает R на поиск вызываемой строковой переменной Emp , которая предположительно содержит имя другой переменной, содержащей веса, как здесь:

 df <- data.frame(Region = c("Asia","Asia","Africa","Europe","Europe"),
             x = c(120,40,10,67,110),
             Sales18 = c(12310, 4510, 1140, 5310, 16435),
             Sales19 = c(15670, 6730, 1605, 6120, 1755))

Emp <- 'x'

df %>% group_by(Region) %>% 
  summarise(sales18 = mean(Sales18, na.rm = T),
            sales19 = mean(Sales19, na.rm = T),
            weightedsales18 = weighted.mean(Sales18, .data[[Emp]], na.rm = T),
            weightedsales19 = weighted.mean(Sales19, .data[[Emp]], na.rm = T))

# A tibble: 3 x 5
  Region sales18 sales19 weightedsales18 weightedsales19
  <chr>    <dbl>   <dbl>           <dbl>           <dbl>
1 Africa   1140    1605            1140            1605 
2 Asia     8410   11200           10360           13435 
3 Europe  10872.   3938.          12224.           3407.
 

Так как у вас нет такого рода Emp , R выдает ошибку.

Что делать? Просто процитируйте Emp внутри [[ :

 df <- data.frame(Region = c("Asia","Asia","Africa","Europe","Europe"),
                 Emp = c(120,40,10,67,110),
                 Sales18 = c(12310, 4510, 1140, 5310, 16435),
                 Sales19 = c(15670, 6730, 1605, 6120, 1755))


df %>% group_by(Region) %>% 
  summarise(sales18 = mean(Sales18, na.rm = T),
            sales19 = mean(Sales19, na.rm = T),
            weightedsales18 = weighted.mean(Sales18, .data[['Emp']], na.rm = T),
            weightedsales19 = weighted.mean(Sales19, .data[['Emp']], na.rm = T))

# A tibble: 3 x 5
  Region sales18 sales19 weightedsales18 weightedsales19
  <chr>    <dbl>   <dbl>           <dbl>           <dbl>
1 Africa   1140    1605            1140            1605 
2 Asia     8410   11200           10360           13435 
3 Europe  10872.   3938.          12224.           3407.