Вот dput()
деконструкция данных.
library(tidyverse)
structure(list(L1 = c("Age Class", "Age Class", "Age Class",
"Age Class", "Gender", "Gender", "Gender", "Age Class", "Age Class",
"Age Class", "Gender", "Gender", "Age Class", "Age Class", "Age Class",
"Gender"), L2 = c("Older Youth", "Older Youth", "Younger Youth",
"Younger Youth", "Female", "Female", "Female", "Younger Youth",
"Older Youth", "Older Youth", "Male", "Male", "Younger Youth",
"Older Youth", "Older Youth", "Female"), scr = c(0.78125, 0.90625,
0.90625, 0.6875, 0.875, 0.78125, 1, 0.65625, 0.75, 0.59375, 0.8125,
0.75, 0.65625, 0.6875, 0.75, 0.75)), row.names = c(NA, -16L), class = "data.frame")
Я хочу использовать медианную и стандартную ошибку в качестве общей статистики.
Снова выполните медианную и стандартную ошибку, сгруппировав L1 и L2.
Выполните тест Уилкоксона в пределах L1, поскольку он содержит 2 фактора для каждой группы.
Объедините эти три списка: а) на bind_rows()
из результатов шагов 1 и 2. Затем left_join()
значения p.values (шаг 3) с набором данных.
Желаемый конечный результат будет выглядеть как на картинке ниже:
Я попытался создать list()
для каждого из шагов внутри dplyr
, но обработка list()
, то есть выбор или фильтрация в dplyr
или конвейерной среде, является громоздкой. Тем не менее, следующий фрагмент работает, но я хочу максимально сократить обработку списков. Особенно вторую половину кода, я думаю, можно сократить или упростить.
df %>%
list(
a = {.} %>% mutate(L1 = "All", L2 = "All") %>% summarise(mdn=median(scr), se=(sd(scr)/sqrt(length(scr))), .by = c(L1, L2)),
b = {.} %>% summarise(mdn=median(scr), se=(sd(scr)/sqrt(length(scr))), .by = c(L1, L2)),
c = {.} %>% summarise(pv= wilcox.test(scr~L2)$p.value, .by = L1)) %>%
list(
d= {.} %>% keep(names(.) %in% c('a','b')) %>% bind_rows(), #Reduce codes from this line
c= {.} %>% pluck("c")) %>%
keep(names(.) %in% c('c','d')) %>%
reduce(left_join, by = "L1") #to this line
Хотел бы знать, есть ли какая-либо возможность вложения кадров данных. Любой purrr::map()
способ сокращения скриптов/текстов.
Спасибо @AdrianoMello за ответ. Теоретически я хочу, чтобы это было именно так, но с объектом list()
это не работает. К вашему сведению, на самом деле после первой операции создается 4 вложенных объекта/элемента. Один — набор данных, а остальные 3 — a, b и c.
Я думаю, что мой вопрос был неясен (извините за это). Я имею в виду: почему вы хотите использовать list
, когда bind_rows( a left_join(b, c))
обеспечивает ожидаемый результат (здесь это сработало)? Будут ли в качестве входных данных для этих операций использоваться другие наборы данных?
На самом деле я хотел, чтобы один кусок конвейерного кода делал все. Обычно я избегаю создания множества объектов в глобальной среде. Однако нашел решение и ответил в теме.
По мнению Адриано, мне кажется, что самый простой способ сделать это (безусловно) - просто выполнить эти три очень разные операции отдельно, а затем связать результаты вместе:
# Overall statistics
out_1 <- df %>%
summarize(
mdn = median(scr),
se = sd(scr) / sqrt(n())
) %>%
mutate(
L1 = "All",
L2 = "All"
)
# Statistics by group
out_2 <- df %>%
group_by(L1, L2) %>%
summarize(
mdn = median(scr),
se = sd(scr) / sqrt(n())
)
# Wilcoxon test
out_3 <- df %>%
group_by(L1) %>%
summarize(
pv = wilcox.test(scr ~ L2)$p.value
)
# Combine
out <- out_1 %>%
bind_rows(out_2) %>%
left_join(out_3)
mdn se L1 L2 pv
1 0.750000 0.02702097 All All NA
2 0.750000 0.04224854 Age Class Older Youth 0.5894851
3 0.671875 0.06034703 Age Class Younger Youth 0.5894851
4 0.828125 0.05615588 Gender Female 0.6385921
5 0.781250 0.03125000 Gender Male 0.6385921
Если вы собираетесь делать это неоднократно, вы можете сделать из этого функцию.
Или, если вы хотите сделать все это в одном канале и вас устраивает, что вывод будет в немного другом формате:
df %>%
mutate(
mdn_overall = median(scr),
se_overall = sd(scr) / sqrt(n())
) %>%
group_by(L1) %>%
mutate(
pv = wilcox.test(scr ~ L2)$p.value
) %>%
group_by(L1, L2, mdn_overall, se_overall, pv) %>%
summarize(
mdn_group = median(scr),
se_group = sd(scr) / sqrt(n())
)
L1 L2 mdn_overall se_overall pv mdn_group se_group
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Age Class Older Youth 0.75 0.0270 0.589 0.75 0.0422
2 Age Class Younger Youth 0.75 0.0270 0.589 0.672 0.0603
3 Gender Female 0.75 0.0270 0.639 0.828 0.0562
4 Gender Male 0.75 0.0270 0.639 0.781 0.0312
Большое спасибо @ila за усилия. К счастью, я нашел решение и ответил в теме.
Теперь мы можем сгруппировать его внутри summarise
и mutate
с помощью .by = ...
. Кажется, это более безопасный вариант для последовательных операций (ИМХО). При использовании group_by
всегда полезно ungroup
позже или использовать summarise( .groups = ... )
.
Использование %$%
вместо %>%
(из magrittr) сохранит независимость данных и не будет принимать первый аргумент в канал, и, следовательно, будет достаточно просто выполнить %$% left_join(bind_rows(.$a, .$b), .$c)
так же, как обычный способ фрейма данных.
library(magrittr)
df %$%
list(
a = {.} %>% mutate(L1 = "All", L2 = "All") %>% summarise(mdn=median(scr), se=(sd(scr)/sqrt(length(scr))), .by = c(L1, L2)),
b = {.} %>% summarise(mdn=median(scr), se=(sd(scr)/sqrt(length(scr))), .by = c(L1, L2)),
c = {.} %>% summarise(pv= wilcox.test(scr~L2)$p.value, .by = L1)
) %$%
left_join(bind_rows(.$a, .$b), .$c)
Мне очень понравилось ваше собственное решение, я приму его к сведению!
Что я имел в виду:
new_df <- df %>%
summarise(
L1 = "All", L2 = "All",
mdn = median(scr),
se=(sd(scr)/sqrt(length(scr)))) %>%
bind_rows(
df %>%
summarise(
.by = c(L1, L2),
mdn = median(scr),
se = (sd(scr)/sqrt(length(scr)))) %>%
left_join(
df %>%
summarise(
.by = L1,
pv = wilcox.test(scr~L2)$p.value),
by = "L1"))
Выход:
> new_df
L1 L2 mdn se pv
1 All All 0.750000 0.02702097 NA
2 Age Class Older Youth 0.750000 0.04224854 0.5894851
3 Age Class Younger Youth 0.671875 0.06034703 0.5894851
4 Gender Female 0.828125 0.05615588 0.6385921
5 Gender Male 0.781250 0.03125000 0.6385921
Существует три разные операции с разным набором переменных, поэтому
purrr::map()
может нечего предложить. Какая мотивация делать это сlist
вместо простоbind_rows( "a", left_join( "b", "c" ))
?