Aplicar función condicionalmente

Tengo un dataframe como este:

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

¿Hay alguna forma de calcular los resultados mediante la aplicación de una función con condiciones? En el ejemplo anterior, esa condición son todas las iteraciones de un experimento en particular.

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

Estoy pensando en la función “aplicar”, pero no puedo encontrar la manera de hacerlo funcionar.

Hay muchas alternativas para hacer esto. Tenga en cuenta que si está interesado en otra función diferente de sum , simplemente cambie el argumento FUN=any.function , por ejemplo, si quiere mean , var length , etc, simplemente conecte esas funciones al argumento FUN , por ejemplo, FUN=mean , FUN=var y así sucesivamente. Exploremos algunas alternativas:

función aggregate en la base.

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

¿O tal vez tapply ?

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

También ddply del paquete 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 

También el paquete 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 

Usar sapply y split , equivalente a tapply .

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

Si le preocupa el tiempo, data.table es su amigo:

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

No es tan popular, pero el paquete doBy es bueno (¡equivalente a aggregate , incluso en syntax!)

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

También by ayuda en esta situación

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

Si desea que el resultado sea una matriz, utilice cbind o rbind

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

sqldf del paquete sqldf también podría ser una buena opción

 > 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 también funciona (solo cuando FUN=sum )

 > xtabs(results ~ experiment, data=DF) experiment AB 86.3 986.0