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.table
así:
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, dplyr
ya 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_at
así:
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 get
y :=
(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.