Подтвердить что ты не робот

Применить функцию условно

У меня есть dataframe, как это:

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

Есть ли способ получить результаты, применяя функцию с условиями. В приведенном выше примере это условие - все итерации конкретного эксперимента.

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

Я думаю о "применении" функции, но не могу найти способ заставить ее работать.

4b9b3361

Ответ 1

Есть много альтернатив для этого. Обратите внимание: если вас интересует другая функция, отличная от sum, просто измените аргумент FUN=any.function, например, если вы хотите mean, var length и т.д., А затем просто подключите эти функции к FUN, например FUN=mean, FUN=var и т.д. Давайте рассмотрим некоторые альтернативы:

aggregate в базе.

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

Или, может быть, tapply?

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

Также ddply из пакета 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

Также пакет 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

Использование sapply и split, эквивалентное tapply.

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

Если вы беспокоитесь о сроках, data.table является вашим другом:

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

Не так популярен, но пакет doBy хорош (эквивалентен aggregate, даже в синтаксисе!)

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

Также by помогает в этой ситуации

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

Если вы хотите, чтобы результат был матрицей, используйте либо cbind, либо rbind

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

sqldf из пакета sqldf также может быть хорошим вариантом

> 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 также работает (только когда FUN=sum)

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