Вы хотите использовать dplyr и case_when
, чтобы свернуть ряд столбцов индикатора в один столбец. Проблема в том, что я хочу иметь возможность свернуть неопределенное / динамическое количество столбцов.
Рассмотрим следующий набор данных, gear
был разделен на ряд столбцов индикаторов.
library(dplyr)
data(mtcars)
mtcars = mtcars %>%
mutate(g2 = ifelse(gear == 2, 1, 0),
g3 = ifelse(gear == 3, 1, 0),
g4 = ifelse(gear == 4, 1, 0)) %>%
select(g2, g3, g4)
Я пытаюсь написать функцию, которая делает обратное.
Когда я знаю, сколько случаев это можно сделать следующим образом:
combine_indices = function(db, cols, vals){
db %>% mutate(new_col = case_when(!!sym(cols[1]) == 1 ~ vals[1],
!!sym(cols[2]) == 1 ~ vals[2],
!!sym(cols[3]) == 1 ~ vals[3]))
}
cols = c("g2", "g3", "g4")
vals = c(2,3,4)
combine_indices(mtcars, cols, vals)
Однако я хотел бы, чтобы функция combine_indices
обрабатывала любое количество столбцов индекса (сейчас она работает ровно для трех).
Согласно документации (?case_when
), «если ваши шаблоны хранятся в списке, вы можете объединить его с !!!
». Но я не могу заставить это работать:
patterns = list(sym(cols[1] == 1 ~ vals[1],
sym(cols[2] == 1 ~ vals[2],
sym(cols[3] == 1 ~ vals[3])
mtcars %>% mutate(new_col = case_when(!!!patterns))
Создает только новый столбец, заполненный NA.
Если бы !!!patterns
работал, то было бы просто взять списки cols
и vals
и сгенерировать patterns
. Однако я не могу правильно сформулировать вопросы. Надеюсь, что кто-то, более знакомый с вопросами, знает, как это сделать.
Обратите внимание: некоторые похожие вопросы SO были решены с использованием объединений или других функций. Однако я ограничен использованием case_when
из-за того, как он преобразуется в sql при использовании dbplyr.