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

#r #dplyr

#r #dplyr

Вопрос:

Окей, у меня возникли проблемы с чем-то, что должно быть простым. Если у меня есть фрейм данных, подобный этому:

 x <- data.frame(a = seq(1,3), b = seq(2,4), c = seq(3,5), d = seq(4,6), b2 = seq(5,7), c2 = seq(6,8), d2 = seq(7,9))

# a b c d b2 c2 d2
# 1 2 3 4 5  6  7
# 2 3 4 5 6  7  8
# 3 4 5 6 7  8  9 
  

Я хочу использовать mutate_at для создания новых столбцов на основе результата из b / b2, c / c2 и т.д. Когда я пытаюсь:

 myvars <- c(2:4)
dvars <- c(5:7)
x <- x %>%
mutate_at(vars(myvars), funs('_new' = vars(myvars) / vars(dvars)))
  

Я получаю сообщение об ошибке «Ошибка оценки: нечисловой аргумент двоичного оператора».

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

Ответ №1:

Вы могли бы напрямую сделать

 x[myvars]/x[dvars]

#          b         c         d
#1 0.4000000 0.5000000 0.5714286
#2 0.5000000 0.5714286 0.6250000
#3 0.5714286 0.6250000 0.6666667
  

Я не уверен, что вы могли бы сделать это с помощью mutate_at однако, вы можете использовать map2_df из purrr

 purrr::map2_df(x[myvars], x[dvars], ~ .x/.y)
  

ИЛИ с mapply

 mapply("/", x[myvars], x[dvars])
  

Комментарии:

1. Я надеялся понять, почему это не работает с mutate_at, но я думаю, что mapply — лучшее решение для подобной проблемы. Спасибо!

2. @GreenManXY да, muatate.. применяет функцию к каждому столбцу. Здесь у нас есть две группы столбцов, поэтому лучше использовать mapply / map2 .

Ответ №2:

Мы можем создать это в выражении, а затем вычислить с помощью parse_exprs из rlang

 library(dplyr)
expr1 <- paste0(names(x)[myvars], "/", names(x)[dvars])
x %>% 
     mutate(!!! rlang::parse_exprs(expr1))