Sé que hay varias preguntas similares por aquí, pero ninguna de ellas parece abordar el problema preciso que estoy teniendo.
set.seed(4)
df = data.frame(
Key = c("A", "B", "A", "D", "A"),
Val1 = rnorm(5),
Val2 = runif(5),
Val3 = 1:5
)
Quiero poner a cero los valores de las columnas de valor para las filas donde Clave == "A" Los nombres de columna se referencian a través de un grep:
cols = grep("Val", names(df), value = TRUE)
Normalmente para lograr lo que quiero en este caso, usaría data.tableasí:
library(data.table)
df = as.data.table(df)
df[Key == "A", (cols) := 0]
Y la salida deseada es así:
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
Sin embargo, esta vez necesito usarlo, dplyrya que estoy trabajando en un proyecto de equipo donde todos lo usan. Los datos que acabo de proporcionar son ilustrativos y mis datos reales son> 5m de filas con 16 columnas de valor para actualizar. La única solución que se me ocurre es usar mutate_atasí:
df %>% mutate_at(.vars = vars(cols), .funs = function(x) ifelse(df$Key == "A", 0, x))
Sin embargo, esto parece ser extremadamente lento en mis datos reales. Esperaba encontrar una solución que fuera más elegante y, lo que es más importante, más rápida.
He intentado muchas combinaciones usando map, sin comillas usando !!, usando gety :=(que molestamente puede enmascararse en el :=archivo data.table), etc., pero creo que mi comprensión de cómo funcionan estos simplemente no es lo suficientemente profunda como para construir una solución válida.