Je sais que je peux * re * nommer les colonnes après avoir agrégé les données:
blubb <- aggregate(dat$two ~ dat$one, ...)
colnames(blubb) <- c("One", "Two")
Aucun problème avec ça. Mais existe-t-il un moyen d'agréger et de nommer les colonnes en une seule fois? Un peu comme:
blubb <- aggregate( ... , cols = c("One", "Two"))
Il serait particulièrement agréable (et à l'épreuve des fautes de frappe) d'attraper en quelque sorte les noms de colonnes d'origine et de faire comme:
blubb <- aggregate( ... , cols = c(name_of_dat$one, name_of_dat$two."_Mean"))
Vous pouvez utiliser setNames
comme dans:
blubb <- setNames(aggregate(dat$two ~ dat$one, ...), c("One", "Two"))
Alternativement, vous pouvez contourner la méthode de la formule lisse et utiliser une syntaxe comme:
blubb <- aggregate(list(One = dat$one), list(Two = dat$two), ...)
Cette mise à jour est juste pour vous aider à démarrer vous-même la dérivation d'une solution.
Si vous inspectez le code pour stats:::aggregate.formula
, Vous verrez les lignes suivantes vers la fin:
if (is.matrix(mf[[1L]])) {
lhs <- as.data.frame(mf[[1L]])
names(lhs) <- as.character(m[[2L]][[2L]])[-1L]
aggregate.data.frame(lhs, mf[-1L], FUN = FUN, ...)
}
else aggregate.data.frame(mf[1L], mf[-1L], FUN = FUN, ...)
Si tout ce que vous voulez faire est d'ajouter le nom de la fonction à la variable qui a été agrégée, vous pouvez peut-être changer cela en quelque chose comme:
if (is.matrix(mf[[1L]])) {
lhs <- as.data.frame(mf[[1L]])
names(lhs) <- as.character(m[[2L]][[2L]])[-1L]
myOut <- aggregate.data.frame(lhs, mf[-1L], FUN = FUN, ...)
colnames(myOut) <- c(names(mf[-1L]),
paste(names(lhs), deparse(substitute(FUN)), sep = "."))
}
else {
myOut <- aggregate.data.frame(mf[1L], mf[-1L], FUN = FUN, ...)
colnames(myOut) <- c(names(mf[-1L]),
paste(strsplit(gsub("cbind\\(|\\)|\\s", "",
names(mf[1L])), ",")[[1]],
deparse(substitute(FUN)), sep = "."))
}
myOut
Cela capture essentiellement la valeur entrée pour FUN
en utilisant deparse(substitute(FUN))
, vous pouvez donc probablement modifier la fonction pour accepter un suffixe personnalisé, ou peut-être même un vecteur de suffixes. Cela peut probablement être amélioré un peu avec du travail, mais je ne vais pas le faire!
Voici n Gist avec ce concept appliqué, créant une fonction nommée "myAgg".
Voici un exemple de sortie uniquement des noms de colonne résultants :
> names(myAgg(weight ~ feed, data = chickwts, mean))
[1] "feed" "weight.mean"
> names(myAgg(breaks ~ wool + tension, data = warpbreaks, sum))
[1] "wool" "tension" "breaks.sum"
> names(myAgg(weight ~ feed, data = chickwts, FUN = function(x) mean(x^2)))
[1] "feed" "weight.function(x) mean(x^2)"
Notez que seul le nom de variable agrégée change. Mais notez également que si vous utilisez une fonction personnalisée, vous vous retrouverez avec un nom de colonne vraiment étrange!
La réponse à votre première question est oui. Vous pouvez certainement inclure les noms de colonne dans la fonction d'agrégation. En utilisant les noms de votre exemple ci-dessus:
blubb <- aggregate(dat,list(One=dat$One,Two=dat$Two),sum)
J'aime la partie sur l'extraction éventuelle des noms de colonnes d'origine automatiquement. Si je le découvre, je le posterai.
Si vous préférez écrire des agrégats sous la forme formula
, la documentation montre l'utilisation de cbind
. Et cbind
vous permet de nommer ses arguments, qui sont utilisés par aggregate
.
blubb <- aggregate(cbind(Two = dat$two) ~ cbind(One = dat$one), ...)
L'agrégation de plus d'une colonne par plus d'un facteur de regroupement pourrait se faire comme:
blubb <- aggregate(cbind(x = varX, y = varY, varZ) ~ cbind(a = facA) + cbind(b = facB) + facC, data=dat, FUN=sum)
et si vous souhaitez utiliser plusieurs fonctions:
aggregate(cbind(cases=ncases, ncontrols) ~ cbind(alc=alcgp) + tobgp, data = esoph, FUN = function(x) c("mean" = mean(x), "median" = median(x)))
# alc tobgp cases.mean cases.median ncontrols.mean ncontrols.median
#1 1 0-9g/day 1.5000000 1.0000000 43.500000 47.000000
#2 2 0-9g/day 5.6666667 4.0000000 29.833333 34.500000
#...
ce qui ajoute au nom de colonne la fonction d'agrégation utilisée.
Mais cbind
remplace factors
par leurs codes internes. Pour éviter cela, vous pouvez utiliser:
with(esoph, aggregate(data.frame(cases=ncases, ncontrols), data.frame(alc=alcgp, tobgp), FUN = function(x) c("mean" = mean(x), "median" = median(x))))
# alc tobgp cases.mean cases.median ncontrols.mean ncontrols.median
#1 0-39g/day 0-9g/day 1.5000000 1.0000000 43.500000 47.000000
#2 40-79 0-9g/day 5.6666667 4.0000000 29.833333 34.500000
#...