Как я могу использовать `mutate_at` для списка столбцов в таблице? - PullRequest
1 голос
/ 18 марта 2020

У меня столбец структурирован следующим образом:

df <- 
  tibble(
    x = 1:3, 
    light_93 = list(1:3, 5:7, 18:20),
    light_94 = list(3:5, 9:11, 18:20),
    light_95 = list(5:7, 44:46, 30:32))

Я хочу создать несколько новых столбцов, давая среднее значение для каждого light_ списка столбцов. Поэтому я хочу получить такой результат:

out <- 
  df %>% 
  mutate(light_93_mean = map_dbl(light_93, mean),
         light_94_mean = map_dbl(light_94, mean),
         light_95_mean = map_dbl(light_95, mean))

Могу ли я использовать mutate_at для автоматизации этого? (У меня есть сотни столбцов списка.) Я не могу понять, как заставить это работать в тибле.

Ответы [ 2 ]

2 голосов
/ 18 марта 2020

Укажите столбцы для применения в аргументе vars в mutate_at, затем в каждом столбце l oop над list с map и получите mean

library(dplyr)
library(purrr)
df %>%
     mutate_at(vars(starts_with('light')), 
        list(mean = ~ map_dbl(., mean)))
# A tibble: 3 x 7
#      x light_93  light_94  light_95  light_93_mean light_94_mean light_95_mean
#  <int> <list>    <list>    <list>            <dbl>         <dbl>         <dbl>
#1     1 <int [3]> <int [3]> <int [3]>             2             4             6
#2     2 <int [3]> <int [3]> <int [3]>             6            10            45
#3     3 <int [3]> <int [3]> <int [3]>            19            19            31

Или с использованием версии devel с across и mutate

df %>% 
     mutate(across(starts_with('light'), ~ map_dbl(., mean), names = "{col}_mean"))
# A tibble: 3 x 7
#      x light_93  light_94  light_95  light_93_mean light_94_mean light_95_mean
#  <int> <list>    <list>    <list>            <dbl>         <dbl>         <dbl>
#1     1 <int [3]> <int [3]> <int [3]>             2             4             6
#2     2 <int [3]> <int [3]> <int [3]>             6            10            45
#3     3 <int [3]> <int [3]> <int [3]>            19            19            31

Можно также использовать разные наборы столбцов с различными функциями

df %>% 
    mutate(across(starts_with('light'), ~ map_dbl(., mean), names = "{col}_mean"),
           across(matches('(94|95)$'), ~ map_dbl(., sum), names = "{col}_sum"))
# A tibble: 3 x 9
#      x light_93  light_94  light_95  light_93_mean light_94_mean light_95_mean light_94_sum light_95_sum
#  <int> <list>    <list>    <list>            <dbl>         <dbl>         <dbl>        <dbl>        <dbl>
#1     1 <int [3]> <int [3]> <int [3]>             2             4             6           12           18
#2     2 <int [3]> <int [3]> <int [3]>             6            10            45           30          135
#3     3 <int [3]> <int [3]> <int [3]>            19            19            31           57           93
0 голосов
/ 18 марта 2020

В базе R мы можем выбрать столбцы, которые начинаются с "light", используя grep, вычислить mean каждого списка и добавить в качестве нового столбца.

cols <- grep('^light', names(df), value = TRUE)
df[paste0(cols, "_mean")] <- lapply(df[cols], function(x) sapply(x, mean))
df

# A tibble: 3 x 7
#      x light_93  light_94  light_95  light_93_mean light_94_mean light_95_mean
#  <int> <list>    <list>    <list>            <dbl>         <dbl>         <dbl>
#1     1 <int [3]> <int [3]> <int [3]>             2             4             6
#2     2 <int [3]> <int [3]> <int [3]>             6            10            45
 #3    3 <int [3]> <int [3]> <int [3]>            19            19            31
...