Применить функцию к подмножеству столбцов, используя purr и dplyr - PullRequest
1 голос
/ 25 марта 2020

Я новичок в пакете purr, но мне нравится то, что я о нем знаю.

Используя только пакеты tidyverse, я хотел бы иметь возможность добавить столбец, который является результатом функция применяется к подмножеству столбцов в наборе данных.

Вот некоторые игрушечные данные. Последовательность столбцов факторов

df <- data.frame(a_1 = factor(rep(letters[1:3], times = 5)),
                 a_2 = factor(rep(letters[1:3], times = 5)),
                 a_3 = factor(rep(letters[1:3], times = 5)),
                 b_1 = factor(rep(letters[1:3], times = 5)),
                 b_2 = factor(rep(letters[1:3], times = 5)),
                 b_3 = factor(rep(letters[1:3], times = 5)))

df

# output
#  a_1 a_2 a_3 b_1 b_2 b_3
# 1    a   a   a   a   a   a
# 2    b   b   b   b   b   b
# 3    c   c   c   c   c   c
# 4    a   a   a   a   a   a
# 5    b   b   b   b   b   b
# 6    c   c   c   c   c   c
# 7    a   a   a   a   a   a
# 8    b   b   b   b   b   b
# 9    c   c   c   c   c   c
# 10   a   a   a   a   a   a
# 11   b   b   b   b   b   b
# 12   c   c   c   c   c   c
# 13   a   a   a   a   a   a
# 14   b   b   b   b   b   b
# 15   c   c   c   c   c   c

Следующая функция, через purr::map_df и dplyr::select, циклически перебирает столбцы df, начинающиеся с a_, преобразует их в числовой класс c, находит среднее значение этих столбцов, затем умножается на 3.

rowMeans(purrr::map_df(.x = df %>% dplyr::select(grep("a_", names(.))),
                       .f = function(x) x <- as.numeric(x))*3)

# output
# [1] 3 6 9 3 6 9 3 6 9 3 6 9 3 6 9

Это правильный вывод, но это вектор.

Как использовать функцию tidyverse, как добавить результат моей функции в существующий набор данных df как новый столбец, а не как вектор?

Что-то, связанное с dplyr::mutate Полагаю, но я не могу решить это.

1 Ответ

1 голос
/ 25 марта 2020

Вы можете использовать pmap_dbl:

library(dplyr)
library(purrr)

df %>%  
   mutate(mean_vec = pmap_dbl(select(., starts_with('a_')), 
                         ~mean(as.numeric(c(...)) * 3)))


#   a_1 a_2 a_3 b_1 b_2 b_3 mean_vec
#1    1   1   1   a   a   a        3
#2    2   2   2   b   b   b        6
#3    3   3   3   c   c   c        9
#4    1   1   1   a   a   a        3
#5    2   2   2   b   b   b        6
#6    3   3   3   c   c   c        9
#7    1   1   1   a   a   a        3
#8    2   2   2   b   b   b        6
#9    3   3   3   c   c   c        9
#10   1   1   1   a   a   a        3
#11   2   2   2   b   b   b        6
#12   3   3   3   c   c   c        9
#13   1   1   1   a   a   a        3
#14   2   2   2   b   b   b        6
#15   3   3   3   c   c   c        9

или другой вариант:

df %>%
  mutate_at(vars(starts_with('a')), as.numeric) %>%
  mutate(mean_vec = rowMeans(select(., starts_with('a_')) * 3))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...