webentwicklung-frage-antwort-db.com.de

Spalten innerhalb des Aggregats in R benennen

Ich weiß, dass ich Spalten * umbenennen * kann, nachdem ich die Daten aggregiert habe:

blubb <- aggregate(dat$two ~ dat$one, ...)
colnames(blubb) <- c("One", "Two")

Daran ist nichts auszusetzen. Aber gibt es eine Möglichkeit, die Spalten auf einmal zu aggregieren und zu benennen? So in etwa wie:

blubb <- aggregate( ... , cols = c("One", "Two"))

Besonders schön (und schreibgeschützt) wäre es, wenn man die ursprünglichen Spaltennamen irgendwie fängt und wie folgt vorgeht:

blubb <- aggregate( ... , cols = c(name_of_dat$one, name_of_dat$two."_Mean"))
51
user1322720

Sie können setNames wie folgt verwenden:

blubb <- setNames(aggregate(dat$two ~ dat$one, ...), c("One", "Two"))

Alternativ können Sie die glatte Formelmethode umgehen und die folgende Syntax verwenden:

blubb <- aggregate(list(One = dat$one), list(Two = dat$two), ...)

Aktualisieren

Dieses Update soll Ihnen nur dabei helfen, eine eigene Lösung zu finden.

Wenn Sie den Code auf stats:::aggregate.formula Überprüfen, werden am Ende die folgenden Zeilen angezeigt:

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, ...)

Wenn Sie lediglich den Funktionsnamen an die aggregierte Variable anhängen möchten, können Sie dies möglicherweise in Folgendes ändern:

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

Dies erfasst im Wesentlichen den für FUN eingegebenen Wert mit deparse(substitute(FUN)), sodass Sie die Funktion möglicherweise so ändern können, dass sie ein benutzerdefiniertes Suffix oder sogar einen Vektor von Suffixen akzeptiert. Dies kann wahrscheinlich mit ein wenig Arbeit ein wenig verbessert werden, aber ich werde es nicht tun!

Hier ist a Gist , wobei dieses Konzept angewendet wird und eine Funktion mit dem Namen "myAgg" erstellt wird.

Hier ist eine Beispielausgabe nur der resultierenden Spaltennamen :

> 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)"

Beachten Sie, dass sich nur der Name der aggregierten Variablen ändert. Beachten Sie jedoch auch, dass Sie bei Verwendung einer benutzerdefinierten Funktion einen wirklich seltsamen Spaltennamen erhalten!

67

Die Antwort auf Ihre erste Frage lautet ja. Sie können die Spaltennamen durchaus in die Aggregatfunktion aufnehmen. Verwenden Sie die Namen aus Ihrem obigen Beispiel:

blubb <- aggregate(dat,list(One=dat$One,Two=dat$Two),sum)

Ich mag den Teil, in dem es darum geht, möglicherweise die ursprünglichen Spaltennamen automatisch einzugeben. Wenn ich es herausfinde, werde ich es posten.

9
orville jackson

Falls Sie es vorziehen, Aggreagtes als formula zu schreiben, wird in der Dokumentation die Verwendung von cbind gezeigt. Mit cbind können Sie die Argumente benennen, die von aggregate verwendet werden.

blubb <- aggregate(cbind(Two = dat$two) ~ cbind(One = dat$one), ...)

Die Aggregation von mehr als einer Spalte durch mehr als einen Gruppierungsfaktor könnte folgendermaßen erfolgen:

blubb <- aggregate(cbind(x = varX, y = varY, varZ) ~ cbind(a = facA) + cbind(b = facB) + facC, data=dat, FUN=sum)

und wenn Sie mehr als eine Funktion verwenden möchten:

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
#...

das fügt die verwendete Aggregatfunktion zum Spaltennamen hinzu.

Aber cbind ersetzt factors durch ihre internen Codes. Um dies zu vermeiden, können Sie Folgendes verwenden:

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
#...
0
GKi