2013-05-20 14 views
17

ich einen Datenrahmen wie diese:Anwenden Funktion bedingt

experiment iter results 
    A  1  30.0 
    A  2  23.0 
    A  3  33.3 
    B  1  313.0 
    B  2  323.0 
    B  3  350.0 
.... 

Gibt es einen Weg, um Ergebnisse Tally durch eine Funktion mit Bedingungen anzuwenden. Im obigen Beispiel handelt es sich bei dieser Bedingung um alle Iterationen eines bestimmten Experiments.

A sum of results (30 + 23, + 33.3) 
B sum of results (313 + 323 + 350) 

Ich denke an "anwenden" -Funktion, kann aber keinen Weg finden, um es zu arbeiten.

Antwort

43

Es gibt viele Alternativen, dies zu tun. Beachten Sie, wenn Sie in einer anderen Funktion von sum verschiedenen interessiert sind, dann nur das Argument ändern FUN=any.function, beispiel, wenn Sie mean wollen, varlength, etc, dann schließen Sie einfach die Funktionen in FUN Argumente, z.B. FUN=mean, FUN=var und so weiter. Lassen Sie uns einige Alternativen erkunden:

aggregate Funktion in der Basis.

> aggregate(results ~ experiment, FUN=sum, data=DF) 
    experiment results 
1   A 86.3 
2   B 986.0 

Oder vielleicht tapply?

> with(DF, tapply(results, experiment, FUN=sum)) 
    A  B 
86.3 986.0 

Auch ddply aus plyr Paket

> # library(plyr) 
> ddply(DF[, -2], .(experiment), numcolwise(sum)) 
    experiment results 
1   A 86.3 
2   B 986.0 

> ## Alternative syntax 
> ddply(DF, .(experiment), summarize, sumResults = sum(results)) 
    experiment sumResults 
1   A  86.3 
2   B  986.0 

Auch das Paket dplyr

> require(dplyr) 
> DF %>% group_by(experiment) %>% summarise(sumResults = sum(results)) 
Source: local data frame [2 x 2] 

    experiment sumResults 
1   A  86.3 
2   B  986.0 

Verwendung von und split, entspricht tapply.

> with(DF, sapply(split(results, experiment), sum)) 
    A  B 
86.3 986.0 

Wenn Sie Sorge um Timing, data.table ist dein Freund:

> # library(data.table) 
> DT <- data.table(DF) 
> DT[, sum(results), by=experiment] 
    experiment V1 
1:   A 86.3 
2:   B 986.0 

nicht so populär, aber Doby Paket ist schön (entspricht aggregate, auch in der Syntax!

)
> # library(doBy) 
> summaryBy(results~experiment, FUN=sum, data=DF) 
    experiment results.sum 
1   A  86.3 
2   B  986.0 

Auch hilft by in dieser Situation

> (Aggregate.sums <- with(DF, by(results, experiment, sum))) 
experiment: A 
[1] 86.3 
------------------------------------------------------------------------- 
experiment: B 
[1] 986 

Wenn Sie das Ergebnis wollen verwenden eine Matrix dann entweder cbind oder rbind

> cbind(results=Aggregate.sums) 
    results 
A 86.3 
B 986.0 

sqldf von sqldf Paket könnte auch

> library(sqldf) 
> sqldf("select experiment, sum(results) `sum.results` 
     from DF group by experiment") 
    experiment sum.results 
1   A  86.3 
2   B  986.0 

xtabs funktioniert auch eine gute Option sein (nur bei FUN=sum)

> xtabs(results ~ experiment, data=DF) 
experiment 
    A  B 
86.3 986.0 
+8

+1 es nicht umfassender bekommt als das ... –

Verwandte Themen