#r #dplyr
#r #dplyr
Вопрос:
Я использую summarise_at()
для получения среднего значения и стандартной ошибки нескольких переменных по группам.
В выходных данных содержится 1 строка для каждой группы и 1 столбец для каждого вычисляемого количества для каждой группы. Я хотел бы иметь таблицу с 1 строкой для каждой переменной и 1 столбцом для каждого вычисляемого количества:
data <- mtcars
data$condition <- as.factor(c(rep("control", 16), rep("treat", 16)))
data %>%
group_by(condition) %>%
summarise_at(vars(mpg, cyl, wt),
funs(mean = mean, se=sd(.)/sqrt(n())))
# A tibble: 2 x 7
condition mpg_mean cyl_mean wt_mean mpg_se cyl_se wt_se
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 control 18.2 6.5 3.56 1.04 0.387 0.204
2 treat 22.0 5.88 2.87 1.77 0.499 0.257
Вот что, я думаю, было бы более полезным (цифры не имеют смысла):
# MEAN.control, MEAN.treat, SE.control, SE.treat
# mpg 1.5 2.4 .30 .45
# cyl 3.2 1.9 .20 .60
# disp 12.3 17.8 .20 .19
Есть идеи? Новичок в tidyverse
, так что извините, если это слишком просто.
Ответ №1:
funs
Становится устаревшим в dplyr
. Вместо этого используйте list
in summarise_at/mutate_at
. После summarise
шага gather
данные переводятся в формат ‘long’, separate
столбец ‘key’ разделяется на два с помощью разделителя _
, затем unite
‘cond’ и ‘key2’ (после изменения регистра ‘key2’), spread
это в формат ‘wide’ и, при необходимости, измените имена строк на столбец ‘key1’
library(tidyverse)
data %>%
group_by(condition) %>%
summarise_at(vars(mpg, cyl, wt), list(MEAN = ~ mean(.),
SE = ~sd(.)/sqrt(n()))) %>%
gather(key, val, -condition) %>%
separate(key, into = c("key1", "key2")) %>%
unite(cond, key2, condition, sep=".") %>%
spread(cond, val) %>%
column_to_rownames('key1')
# MEAN.control MEAN.treat SE.control SE.treat
#cyl 6.500000 5.875000 0.3872983 0.4989572
#mpg 18.200000 21.981250 1.0369024 1.7720332
#wt 3.560875 2.873625 0.2044885 0.2571034
Комментарии:
1. Любопытно, почему было
funs
изменено наlist
?!2. @NelsonGon Я нахожу здесь открытую проблему, но причина не указана
3. Спасибо!! Я также обновил пример в свете вашего комментария. Я ценю это.
4. @BrianGuay Спасибо за обновление. Но я вижу, что значения отличаются. Это ожидаемый результат
Ответ №2:
Другая возможность может быть:
data %>%
group_by(condition) %>%
summarise_at(vars(mpg, cyl, wt), list(mean = ~ mean(.),
se = ~ sd(.)/sqrt(n()))) %>%
gather(var, val, -condition) %>%
separate(var, c("vars", "var2")) %>%
mutate(var2 = paste(toupper(var2), as.character(condition), sep = "_")) %>%
select(-condition) %>%
spread(var2, val)
vars MEAN_control MEAN_treat SE_control SE_treat
<chr> <dbl> <dbl> <dbl> <dbl>
1 cyl 6.5 5.88 0.387 0.499
2 mpg 18.2 22.0 1.04 1.77
3 wt 3.56 2.87 0.204 0.257
Здесь, после ваших начальных шагов, выполняется преобразование данных от широкого к длинному, исключая столбец «условие». Во-вторых, он разделяет имена переменных на два столбца. В-третьих, он объединяет метрику и условие, причем метрика указывается в верхнем регистре. Наконец, это удаляет избыточную переменную и возвращает ее к желаемому формату.
Или вы можете избежать этого separate()
, используя некоторое регулярное выражение:
data %>%
group_by(condition) %>%
summarise_at(vars(mpg, cyl, wt), list(mean = ~ mean(.),
se = ~ sd(.)/sqrt(n()))) %>%
gather(var, val, -condition) %>%
mutate(vars = gsub("_.*$", "", var),
var2 = gsub(".*\_", "", var)) %>%
mutate(var2 = paste(toupper(var2), as.character(condition), sep = "_")) %>%
select(-condition, -var) %>%
spread(var2, val)
Или с помощью strsplit()
:
data %>%
group_by(condition) %>%
summarise_at(vars(mpg, cyl, wt), list(mean = ~ mean(.),
se = ~ sd(.)/sqrt(n()))) %>%
gather(var, val, -condition) %>%
mutate(vars = sapply(strsplit(var, "_"), function(x) x[1]),
var2 = sapply(strsplit(var, "_"), function(x) x[2])) %>%
mutate(var2 = paste(toupper(var2), as.character(condition), sep = "_")) %>%
select(-condition, -var) %>%
spread(var2, val)
Или вы можете полностью переписать его в:
data %>%
select(mpg, cyl, wt, condition) %>%
gather(vars, val, -condition) %>%
group_by(condition, vars) %>%
summarise(mean = mean(val),
se = sd(val)/sqrt(n())) %>%
ungroup() %>%
gather(var2, val, -c(condition, vars)) %>%
mutate(var2 = paste(toupper(var2), condition, sep = "_")) %>%
select(-condition) %>%
spread(var2, val)
В этом случае сначала выбираются интересующие переменные. Во-вторых, он выполняет преобразование из широкого формата в длинный, исключая столбец «условие». В-третьих, он группирует по условиям и именам переменных и вычисляет показатели. На четвертом шаге выполняется второе преобразование от широкого к длинному, исключая столбец «условие» и столбец с начальными именами переменных. Наконец, он объединяет метрику (верхний регистр) и условие, удаляет избыточную переменную и возвращает ее к желаемому формату.