Je sais qu'il y a plusieurs questions similaires ici, mais aucune ne semble répondre au problème précis que j'ai.
set.seed(4)
df = data.frame(
Key = c("A", "B", "A", "D", "A"),
Val1 = rnorm(5),
Val2 = runif(5),
Val3 = 1:5
)
Je veux mettre à zéro les valeurs des colonnes de valeurs pour les lignes où Clé == "A" Les noms des colonnes sont référencés via un grep
:
cols = grep("Val", names(df), value = TRUE)
Normalement, pour réaliser ce que je veux dans ce cas, j'utiliserais data.table
ceci:
library(data.table)
df = as.data.table(df)
df[Key == "A", (cols) := 0]
Et la sortie souhaitée est comme ceci:
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
Cependant, cette fois, je dois l'utiliser dplyr
car je travaille sur un projet d'équipe où tout le monde l'utilise. Les données que je viens de fournir sont illustratives et mes données réelles sont> 5 m de lignes avec 16 colonnes de valeurs à mettre à jour. La seule solution que j'ai pu trouver est d'utiliser mutate_at
comme ceci:
df %>% mutate_at(.vars = vars(cols), .funs = function(x) ifelse(df$Key == "A", 0, x))
Cependant, cela semble être extrêmement lent sur mes données réelles. J'espérais trouver une solution plus élégante et surtout plus rapide.
J'ai essayé de nombreuses combinaisons en utilisant map
, en ne citant pas en utilisant !!
, en utilisant get
et :=
(qui peuvent être masquées de manière agaçante par la :=
table de données), etc., mais je pense que ma compréhension de la façon dont ces travaux ne sont tout simplement pas assez profonds pour construire une solution valide.