#r #dplyr
#r #dplyr
Вопрос:
У меня есть таблица со столбцами
[Время, var1, var2, var3, var4 … varN]
Мне нужно вычислить среднее / SE за раз для каждого var1, var2 … var n , и я хочу сделать это программно для всех переменных, а не по 1 за раз, что потребовало бы много копирования-вставки.
Раздел 8.2.3 здесь https://tidyeval.tidyverse.org/dplyr.html близко к тому, что я хочу, но мой приведенный ниже код:
x <- as.data.frame(matrix(nrow = 2, ncol = 3))
x[1,1] = 1
x[1,2] = 2
x[1,3] = 3
x[2,1] =4
x[2,2] = 5
x[2,3] = 6
names(x)[1] <- "time"
names(x)[2] <- "var1"
names(x)[3] <- "var2"
grouped_mean3 <- function(.data, ...) {
print(.data)
summary_vars <- enquos(...)
print(summary_vars)
summary_vars <- purrr::map(summary_vars, function(var) {
expr(mean(!!var, na.rm = TRUE))
})
print(summary_vars)
.data %>%
group_by(time)
summarise(!!!summary_vars) # Unquote-splice the list
}
grouped_mean3(x, var("var1"), var("var2"))
Дает
Error in !summary_vars : invalid argument type
И первоначальной причиной является «Необходимо группировать по переменным, найденным в .data
«. и он находит столбец, которого нет в фиктивном «x», который я сгенерировал для целей тестирования. К сожалению, я понятия не имею, что происходит.
Как мне на самом деле извлечь среднее значение из нового summary_vars и добавить его в таблицу .data? summary_vars становится чем-то вроде
[[1]]
mean(~var1, na.rm = TRUE)
[[2]]
mean(~var2, na.rm = TRUE)
Что кажется близким, но требует оценки. Как мне это оценить? !!! не работал.
Для чего это стоит, я попытался подключить пример в dplyr к этому движку R. https://rdrr.io/cran/dplyr/man/starwars.html и это тоже не сработало.
Помочь?
Конечной целью будет таблица в виде
[Время, значение var1, значение var2, значение var3, значение var4 …]
Комментарии:
1. Ваш код выдаст другую ошибку,
object 'summary_vars' not found
. Пожалуйста, убедитесь, что ваш код действительно воспроизводим.2. добавьте
summary_vars <- enquos(...)
в первую строку и удалитеvars
в вызове3. Что-то вроде
library(dplyr) data %>% group_by(Time) %>% summarise(across(var1:varN, mean))
4. @AbdessabourMtk Я добавил, что все еще вижу «Ошибка в!summary_vars: недопустимый тип аргумента». Однако пример обновлен.
5. @Axeman Я обновил страницу, чтобы на ней был код, который вы можете скопировать и вставить, включая создание фиктивной таблицы данных, чтобы вызвать ошибку.
Ответ №1:
Попробуйте это :
library(dplyr)
grouped_mean3 <- function(.data, ...) {
vars <- c(...)
.data %>%
group_by(time) %>%
summarise(across(all_of(vars), mean))
}
grouped_mean3(x, 'var1')
# time var1mean
# <dbl> <dbl>
#1 1 2
#2 4 5
grouped_mean3(x, 'var1', 'var2')
# time var1mean var2mean
# <dbl> <dbl> <dbl>
#1 1 2 3
#2 4 5 6
Комментарии:
1. Спасибо — это приближает меня, но, к сожалению, я все еще кое-что не понимаю — этот код не дает мне таблицу со средними значениями, он выдает мне «x», когда я ее запускаю. x %>% group_by(time) %>% summary(mean_value = mean(var1)) Приведенная выше фраза найдет мне «среднее значение» var1 по времени. Я в основном пытаюсь выяснить, как сделать «var1» переменной, которую можно передавать (например, в виде строки), а затем таким образом я могу добавлять столбцы в исходный фрейм данных «x» из mean_var1, mean_var2, mean_var3…
2. @RNewbie Вы сохранили выходные данные в новой переменной? вот так
x1 <- grouped_mean3(x, 'var1')
, а затем проверьтеx1
результаты. Если это работает не так, как задумано для вас, я бы предложил привести лучший пример и показать ожидаемый результат для него, чтобы мы знали, чего вы ожидаете.3. FWIW это не решает мой первоначальный вопрос, но это: «x %>% group_by (time) %>% summarise_at(vars (names (x) [-1]), funs(mean(., na.rm = TRUE)))», кажется, дает мне все средства, которые яжелание. Итак, это начало.
4. @RNewbie Мой ответ действительно дает результат, аналогичный вашей конечной цели. Я обновил ответ, чтобы показать это. Если это не то, что вы хотите, вам нужно обновить свой пост с точным ожидаемым результатом и лучшими данными. Я не вижу никакого другого «оригинального вопроса» в вашем сообщении.
Ответ №2:
Возможно, это то, что вы ищете?
x %>%
group_by(time) %>%
summarise_at(vars(starts_with('var')), ~mean(.,na.rm=T)) %>%
rename_at(vars(starts_with('var')),funs(paste(.,"mean"))) %>%
merge(x)
С вашими данными (из вашего вопроса) ниже приведен вывод:
time var1mean var2mean var1 var2
1 1 2 3 2 3
2 4 5 6 5 6