Я знаю, що тут є декілька подібних питань, але, схоже, жодне з них не вирішує точну проблему, яку я маю.
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) тощо, але я думаю, що моє розуміння того, як ці роботи просто недостатньо глибокі, щоб побудувати правильне рішення.