En el effondrement récemment publié sur CRAN, j'ai essayé de comprimer la plupart des fonctionnalités courantes de l'application en seulement 2 fonctions :
-
dapply
(Data-Apply) applique des fonctions aux lignes ou (par défaut) aux colonnes de matrices et de data.frames et (par défaut) renvoie un objet du même type et avec les mêmes attributs (sauf si le résultat de chaque calcul est atomique et que drop = TRUE
). Les performances sont comparables à lapply
pour les colonnes data.frame, et environ 2x plus rapide que apply
pour les lignes ou les colonnes de la matrice. Le parallélisme est disponible via mclapply
(uniquement pour MAC).
Syntaxe :
dapply(X, FUN, ..., MARGIN = 2, parallel = FALSE, mc.cores = 1L,
return = c("same", "matrix", "data.frame"), drop = TRUE)
Exemples :
# Apply to columns:
dapply(mtcars, log)
dapply(mtcars, sum)
dapply(mtcars, quantile)
# Apply to rows:
dapply(mtcars, sum, MARGIN = 1)
dapply(mtcars, quantile, MARGIN = 1)
# Return as matrix:
dapply(mtcars, quantile, return = "matrix")
dapply(mtcars, quantile, MARGIN = 1, return = "matrix")
# Same for matrices ...
-
BY
est un générique S3 pour le calcul split-apply-combine avec la méthode vectorielle, matricielle et data.frame. Il est significativement plus rapide que tapply
, by
y aggregate
(et aussi plus rapide que plyr
sur de grandes données dplyr
est cependant plus rapide).
Syntaxe :
BY(X, g, FUN, ..., use.g.names = TRUE, sort = TRUE,
expand.wide = FALSE, parallel = FALSE, mc.cores = 1L,
return = c("same", "matrix", "data.frame", "list"))
Exemples :
# Vectors:
BY(iris$Sepal.Length, iris$Species, sum)
BY(iris$Sepal.Length, iris$Species, quantile)
BY(iris$Sepal.Length, iris$Species, quantile, expand.wide = TRUE) # This returns a matrix
# Data.frames
BY(iris[-5], iris$Species, sum)
BY(iris[-5], iris$Species, quantile)
BY(iris[-5], iris$Species, quantile, expand.wide = TRUE) # This returns a wider data.frame
BY(iris[-5], iris$Species, quantile, return = "matrix") # This returns a matrix
# Same for matrices ...
Des listes de variables de regroupement peuvent également être fournies à la commande g
.
Parler de performance : Un des principaux objectifs de effondrement est d'encourager la programmation haute performance en R et de dépasser le principe du "split-apply-combine". À cette fin, le paquet dispose d'un ensemble complet de fonctions génériques rapides basées sur C++ : fmean
, fmedian
, fmode
, fsum
, fprod
, fsd
, fvar
, fmin
, fmax
, ffirst
, flast
, fNobs
, fNdistinct
, fscale
, fbetween
, fwithin
, fHDbetween
, fHDwithin
, flag
, fdiff
y fgrowth
. Ils effectuent des calculs groupés en un seul passage dans les données (c'est-à-dire sans fractionnement ni recombinaison).
Syntaxe :
fFUN(x, g = NULL, [w = NULL,] TRA = NULL, [na.rm = TRUE,] use.g.names = TRUE, drop = TRUE)
Exemples :
v <- iris$Sepal.Length
f <- iris$Species
# Vectors
fmean(v) # mean
fmean(v, f) # grouped mean
fsd(v, f) # grouped standard deviation
fsd(v, f, TRA = "/") # grouped scaling
fscale(v, f) # grouped standardizing (scaling and centering)
fwithin(v, f) # grouped demeaning
w <- abs(rnorm(nrow(iris)))
fmean(v, w = w) # Weighted mean
fmean(v, f, w) # Weighted grouped mean
fsd(v, f, w) # Weighted grouped standard-deviation
fsd(v, f, w, "/") # Weighted grouped scaling
fscale(v, f, w) # Weighted grouped standardizing
fwithin(v, f, w) # Weighted grouped demeaning
# Same using data.frames...
fmean(iris[-5], f) # grouped mean
fscale(iris[-5], f) # grouped standardizing
fwithin(iris[-5], f) # grouped demeaning
# Same with matrices ...
Dans les vignettes du paquet, je fournis des points de repère. La programmation à l'aide des fonctions rapides est nettement plus rapide que la programmation à l'aide de dplyr o table.de.données surtout sur les petites données, mais aussi sur les grandes.
35 votes
À votre question secondaire : pour beaucoup de choses, plyr est un remplacement direct de
*apply()
yby
. plyr (du moins pour moi) semble beaucoup plus cohérent dans la mesure où je sais toujours exactement quel format de données il attend et exactement ce qu'il va cracher. Cela m'évite bien des tracas.14 votes
Aussi, je recommanderais d'ajouter :
doBy
et les capacités de sélection et d'application dedata.table
.8 votes
sapply
est justelapply
avec l'ajout desimplify2array
sur la sortie.apply
se transforme en vecteur atomique, mais la sortie peut être un vecteur ou une liste.by
divise les cadres de données en sous-cadres de données, mais n'utilise pas la fonctionf
sur les colonnes séparément. Seulement s'il y a une méthode pour la classe 'data.frame'.f
sont appliqués en colonne parby
.aggregate
est générique, de sorte que différentes méthodes existent pour différentes classes du premier argument.10 votes
Mnémotechnique : l pour "liste", s pour "simplifier", t pour "par type" (chaque niveau du groupement est un type).
0 votes
Il existe également certaines fonctions dans le paquet Rfast, comme : eachcol.apply, apply.condition, et d'autres, qui sont plus rapides que les équivalents de R.