Я знаю, что здесь есть несколько подобных вопросов, но ни один из них, кажется, не решает точную проблему, которая у меня есть.
set.seed(4)
df = data.frame(
Key = c("A", "B", "A", "D", "A"),
Val1 = rnorm(5),
Val2 = runif(5),
Val3 = 1:5
)
Я хочу обнулить значения столбцов значений для строк, где Key == "A" На имена столбцов ссылаются через grep
:
cols = grep("Val", names(df), value = TRUE)
Обычно для достижения того, что я хочу в этом случае, я бы использовал data.table
так:
library(data.table)
df = as.data.table(df)
df[Key == "A", (cols) := 0]
И желаемый результат выглядит так:
Key Val1 Val2 Val3
1 A 0.000000 0.00000000 0
2 B -1.383814 0.55925762 2
3 A 0.000000 0.00000000 0
4 D 1.437151 0.05632773 4
5 A 0.000000 0.00000000 0
Однако это время мне нужно использовать, так dplyr
как я работаю над командным проектом, где его используют все. Данные, которые я только что предоставил, являются иллюстративными, и мои реальные данные> 5 миллионов строк с 16 столбцами значений, которые необходимо обновить. Единственное решение, которое я мог бы придумать, это использовать mutate_at
так:
df %>% mutate_at(.vars = vars(cols), .funs = function(x) ifelse(df$Key == "A", 0, x))
Тем не менее, это кажется чрезвычайно медленно на моих реальных данных. Я надеялся найти решение, которое будет более элегантным и, что более важно, более быстрым.
Я пробовал много комбинаций с использованием map
, снятием кавычек, использованием !!
, использованием get
и :=
(что досадно может быть замаскировано :=
в data.table) и т. Д., Но я думаю, что мое понимание того, как эти работы просто недостаточно глубоки, чтобы построить правильное решение.