#r #tidyr #purrr
#r #tidyr #муррр
Вопрос:
Я часто использую шаблон, как показано ниже, где я храню данные в tibble
столбцах списка using, применяю функции к используемым данным purrr::map
, а затем использую pivot_longer
для преобразования в аккуратный формат (длинный).
Есть ли более чистый / более идиоматичный способ сделать это за один шаг, без необходимости каждый раз поворачивать данные?
library(tidyverse)
df <- tibble(n = 5:10)
df$data <- map(df$n, ~rnorm(.x))
df$mean <- map_dbl(df$data, ~mean(.x))
df$median <- map_dbl(df$data, ~median(.x))
# A tibble: 6 x 4
n data mean median
<int> <list> <dbl> <dbl>
1 5 <dbl [5]> -0.0239 -0.324
2 6 <dbl [6]> -0.396 0.0153
3 7 <dbl [7]> 0.506 0.711
4 8 <dbl [8]> 0.463 0.537
5 9 <dbl [9]> -0.248 -0.555
6 10 <dbl [10]> -0.153 -0.293
df <- pivot_longer(df, mean:median)
# A tibble: 12 x 4
n data name value
<int> <list> <chr> <dbl>
1 5 <dbl [5]> mean -0.386
2 5 <dbl [5]> median -0.407
3 6 <dbl [6]> mean -0.190
4 6 <dbl [6]> median -0.451
5 7 <dbl [7]> mean -0.456
6 7 <dbl [7]> median -0.0801
7 8 <dbl [8]> mean -0.0408
8 8 <dbl [8]> median 0.0577
9 9 <dbl [9]> mean 0.273
10 9 <dbl [9]> median 0.410
11 10 <dbl [10]> mean -0.720
12 10 <dbl [10]> median -1.01
Ответ №1:
Я думаю, что у вас уже есть хороший подход, я бы использовал то же самое, объединив все функции в один канал () . %>%
Если вы хотите избежать pivot_longer
шага, вы можете сгруппировать по каждой строке и создать две новые строки для каждой. Это возможно для dplyr
версии 1.0.0 или выше.
library(tidyverse)
df %>%
mutate(data = map(n, rnorm),
group = row_number()) %>%
group_by(group) %>%
summarise(n = n,
data = data,
value = {tmp <- unlist(data);c(median(tmp), mean(tmp))},
name = c('median', 'mean')) %>%
ungroup %>%
select(-group)
# n data value name
# <int> <list> <dbl> <chr>
# 1 5 <dbl [5]> 0.571 median
# 2 5 <dbl [5]> 0.343 mean
# 3 6 <dbl [6]> 0.220 median
# 4 6 <dbl [6]> 0.0419 mean
# 5 7 <dbl [7]> -0.193 median
# 6 7 <dbl [7]> -0.132 mean
# 7 8 <dbl [8]> -0.171 median
# 8 8 <dbl [8]> 0.00583 mean
# 9 9 <dbl [9]> 0.952 median
#10 9 <dbl [9]> 0.471 mean
#11 10 <dbl [10]> 0.684 median
#12 10 <dbl [10]> 0.250 mean
Комментарии:
1. Спасибо! Не могли бы вы объяснить эту строку:
value = {tmp <- unlist(data);c(median(tmp), mean(tmp))}
?2.
data
представляет собой списокmean
иmedian
работает с векторными значениями. Сравните выходныеmean(list(1:5))
данные иmean(unlist(list(1:5)))
. Чтобы избежатьunlist
повторного ввода, я сохраняю его во временной переменнойtmp
и использую вmedian
иmean
.