2013-05-20 31 views
17

Ho un dataframe come questo:Applicare la funzione condizionale

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

C'è un modo per coincidere i risultati mediante l'applicazione di una funzione con condizioni. Nell'esempio sopra, quella condizione è tutte le iterazioni di un particolare esperimento.

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

Penso a funzione "apply", ma non riesco a trovare un modo per farlo funzionare.

risposta

43

Ci sono molte alternative per farlo. Si noti che se siete interessati a un'altra funzione diversa da sum, quindi basta cambiare l'argomento FUN=any.function, per esempio, se si vuole mean, varlength, ecc, quindi basta inserire queste funzioni in FUN argomento, per esempio, FUN=mean, FUN=var e così via. Analizziamo alcune alternative:

aggregate funzione in base.

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

O forse tapply?

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

anche ddply dal pacchetto plyr

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

Anche il pacchetto 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 

Utilizzo di sapply e split, equivalente a tapply.

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

Se siete preoccupazione circa la sincronizzazione, data.table è tuo amico:

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

Non è così popolare, ma il pacchetto Doby è bello (equivalente a aggregate, anche nella sintassi!)

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

anche by aiuta in questa situazione

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

Se si desidera che il risultato sia una matrice quindi utilizzare uno o cbindrbind

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

sqldf dal pacchetto sqldf anche potrebbe essere una buona opzione

> 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 funziona anche (solo quando FUN=sum)

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

+1 non ottiene più completo di quello ... –

Problemi correlati