Je voudrais calculer des variables récapitulatives à partir de plusieurs colonnes dans un bloc de données. Ceci est possible lors de la saisie de tous les noms de lignes, mais je voudrais utiliser starts_with () et des fonctions similaires. Ie
df %>% mutate(A = mean(A1:A3)) df %>% group_by(row_number()) %>% mutate(A = mean(A1:A3)) df %>% group_by(row_number()) %>% mutate(A = mean(starts_with("A")))
Ce qui fonctionne:
library(tidyverse) df %>% mutate(A = (A1 + A2 + A3)/3) df %>% mutate(A = rowMeans(select(., A1:A3)))
Cependant, le premier devient ennuyeux lors de la synthèse de nombreuses variables, tandis que le second devient incroyablement lent très rapidement lorsque résumant de nombreuses lignes. Je soupçonne qu'il doit y avoir une solution plus rapide.
Ce qui ne fonctionne pas:
df <- data.frame(A1 = rnorm(100, 0, 1), A2 = rnorm(100, 0, 1), A3 = rnorm(100, 0, 1), B1 = rnorm(100, 0, 1), B2 = rnorm(100, 0, 1))
Ma question est donc la suivante: y a-t-il un moyen d'utiliser mean () etc. dans mutate () pour calculer les moyennes de lignes, idéalement sans avoir à épeler chaque variable?
3 Réponses :
Utilisez dans votre fonction select
la fonction starts_with
:
df %>% mutate(A = rowMeans(select(., starts_with("A"))))
Si vous recherchez l'aide de select_helpers code > vous en trouvez plusieurs autres.
Merci pour cette réponse. Ceci est essentiellement mon deuxième exemple de «ce qui fonctionne», sauf en utilisant starts_with (). Malheureusement, cela devient très lent très rapidement, alors j'espérais qu'il y aurait une solution plus rapide.
Désolé, j'ai raté la partie performance!
Dans ma version précédente, je pensais que rowMeans
était le problème, mais en fait, ce qui ralentit le calcul est l'utilisation de select
- mieux vaut simplement s'en tenir au famille grep
:
df %>% mutate(A = rowMeans(.[, grepl("^A", names(.))]))
Base R est le plus rapide de mes tests.
J'utiliserai une trame de données plus grande.
library(tidyverse) library(microbenchmark) library(ggplot2) set.seed(1234) n <- 1e4 df <- data.frame(A1 = rnorm(n, 0, 1), A2 = rnorm(n, 0, 1), A3 = rnorm(n, 0, 1), B1 = rnorm(n, 0, 1), B2 = rnorm(n, 0, 1)) mb <- microbenchmark( m1 = df %>% mutate(A = (A1 + A2 + A3)/3), m2 = df %>% mutate(A = rowMeans(select(., A1:A3))), m3 = df %>% mutate(A = reduce(.[, grepl("^A", names(.))], `+`) / ncol(.[, grepl("^A", names(.))])), m4 = rowMeans(df[, grep("^A", names(df))]), m5 = df[, grep("^A", names(df))] %>% rowMeans() ) mb autoplot(mb)
La méthode R purement de base est plus rapide, suivie par le sous-ensemble R de base / dplyr
.
p >
Belle référence! N'affecte pas beaucoup les performances, mais il convient de noter que pour la même sortie, %>% cbind (df, A =.)
(ou quelque chose de similaire) devrait être ajouté à m4
et m5
.
@ arg0naut Ou %>% bind_cols (df, A =.)
, pour utiliser une fonction dplyr
.