Взять среднее значение переменной, определенной строкой в ​​dplyr


Кажется, это должно быть легко, но я в тупике. Я получил грубый навык программирования с dplyr 0,7, но борюсь с этим: как мне программировать на dplyr если переменная, которую я хочу запрограммировать, будет строкой?

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

library(tidyverse)
desired_var <- colnames(iris)[1]
print(desired_var)
"Sepal.Length"

Теперь я хочу сгруппировать по Speciesи взять среднее desired_varт.е. то, что я хочу, это выполнить

iris %>% 
group_by(Species) %>% 
summarise(desired_mean = mean(Sepal.Length))

Но теперь я хочу взять среднее значение столбца, который определяется строкой, хранящейся в desired_var

Я понимаю, как это сделать с "голым" Sepal.Length

desired_var <- quo(Sepal.Length)

iris %>% 
group_by(Species) %>% 
summarise(desired_mean = mean(!!desired_var))

Но как в мире я имею дело с тем, что у меня есть "Sepal.Length" не Sepal.Length то есть desired_var <- "Sepal.Length"?

2 ответа

Решение

1) динамическая переменная с!! sym Use sym (или же parse_expr) как это:

library(dplyr)
library(rlang)

desired_var <- "Sepal.Length"

iris %>% 
  group_by(Species) %>% 
  summarise(desired_mean = mean(!!sym(desired_var))) %>%
  ungroup

давая:

# A tibble: 3 x 2
     Species desired_mean
      <fctr>        <dbl>
1     setosa        5.006
2 versicolor        5.936
3  virginica        6.588

2) summarise_at Как @Phil указывает в комментариях в конкретном случае summarise это можно сделать так без использования каких-либо средств Rlang:

library(dplyr)

desired_var <- "Sepal.Length"

iris %>% 
   group_by(Species) %>% 
   summarise_at(desired_var, funs(mean)) %>%
   ungroup

давая:

# A tibble: 3 x 2
     Species Sepal.Length
      <fctr>        <dbl>
1     setosa        5.006
2 versicolor        5.936
3  virginica        6.588

3) динамическая переменная и имя с!! Если вам нужно установить имя динамически в (1), попробуйте это:

library(dplyr)
library(rlang)

desired_var <- "Sepal.Length"

desired_var_name <- paste("mean", desired_var, sep = "_")

iris %>% 
  group_by(Species) %>% 
  summarise(!!desired_var_name := mean(!!sym(desired_var))) %>%
  ungroup

давая:

# A tibble: 3 x 2
     Species mean_Sepal.Length
      <fctr>             <dbl>
1     setosa             5.006
2 versicolor             5.936
3  virginica             6.588

Вы задаетесь вопросом в tidyeval что является довольно новой особенностью tidyverse (см. здесь) больше используется для создания функций с использованием tidyverse функции. Пока это доступно только с dplyr но план состоит в том, чтобы распространить его на другой tidyverse пакеты.

Для вашей нужды, вам не нужно вдаваться в это, когда summarize_at Сделаю. Эта функция позволяет вам распространять определенные манипуляции, которые вы указываете на любые переменные по вашему выбору:

iris %>% 
  group_by(Species) %>% 
  summarise_at(vars(one_of("Sepal.Length", "Sepal.Width")), funs(desired_mean = mean))

# A tibble: 3 x 3
     Species Sepal.Length_desired_mean Sepal.Width_desired_mean
      <fctr>                     <dbl>                    <dbl>
1     setosa                     5.006                    3.428
2 versicolor                     5.936                    2.770
3  virginica                     6.588                    2.974

Вы можете сохранить список переменных в векторе, а затем использовать этот вектор:

selected_vectors <- c("Sepal.Length", "Sepal.Width")
iris %>% 
  group_by(Species) %>% 
  summarise_at(vars(one_of(selected_vectors)), funs(desired_mean = mean))
Другие вопросы по тегам