Предполагая, что этот фрейм данных (сгенерированный как в посте Прасада, но с set.seed
для воспроизводимости):
set.seed(123)
DF <- data.frame( date = rep(seq(as.Date('1984-04-01'),
as.Date('1984-04-01') + 3, by=1),
1, each=2),
class = rep(c('A','B'), 4),
value = sample(1:8))
, тогда мы рассмотрим семь решений:
1) zoo может дать нам однострочное решение (не считая оператора library
):
library(zoo)
z <- with(read.zoo(DF, split = 2), A - B)
с указанием этой zoo
серии:
> z
1984-04-01 1984-04-02 1984-04-03 1984-04-04
-3 3 3 -5
Также обратите внимание, что as.data.frame(z)
или data.frame(time = time(z), value = coredata(z))
дает фрейм данных;однако вы можете оставить его в качестве объекта зоопарка, поскольку это временной ряд, и другие операции с ним удобнее выполнять в этой форме, например plot(z)
2) sqldf может также дать решение с одним оператором (кроме вызова library
):
> library(sqldf)
> sqldf("select date, sum(((class = 'A') - (class = 'B')) * value) as value
+ from DF group by date")
date value
1 1984-04-01 -3
2 1984-04-02 3
3 1984-04-03 3
4 1984-04-04 -5
3) tapply может использоваться как основа решения, основанного на решении sqldf:
> with(DF, tapply(((class =="A") - (class == "B")) * value, date, sum))
1984-04-01 1984-04-02 1984-04-03 1984-04-04
-3 3 3 -5
4) агрегат можно использовать так же, как sqldf
и tapply
выше (хотя уже появилось немного другое решение, также основанное на aggregate
):
> aggregate(((DF$class=="A") - (DF$class=="B")) * DF["value"], DF["date"], sum)
date value
1 1984-04-01 -3
2 1984-04-02 3
3 1984-04-03 3
4 1984-04-04 -5
5) summaryBy из пакета doBy может предоставить еще одно решение, хотя для его поддержки требуется transform
:
> library(doBy)
> summaryBy(value ~ date, transform(DF, value = ((class == "A") - (class == "B")) * value), FUN = sum, keep.names = TRUE)
date value
1 1984-04-01 -3
2 1984-04-02 3
3 1984-04-03 3
4 1984-04-04 -5
6) remix из пакета remix может сделать это тоже, но с transform
и особенно привлекательным выводом:
> library(remix)
> remix(value ~ date, transform(DF, value = ((class == "A") - (class == "B")) * value), sum)
value ~ date
============
+------+------------+-------+-----+
| | sum |
+======+============+=======+=====+
| date | 1984-04-01 | value | -3 |
+ +------------+-------+-----+
| | 1984-04-02 | value | 3 |
+ +------------+-------+-----+
| | 1984-04-03 | value | 3 |
+ +------------+-------+-----+
| | 1984-04-04 | value | -5 |
+------+------------+-------+-----+
7) summary.formula inпакет Hmisc также имеет хороший вывод:
> library(Hmisc)
> summary(value ~ date, data = transform(DF, value = ((class == "A") - (class == "B")) * value), fun = sum, overall = FALSE)
value N=8
+----+----------+-+-----+
| | |N|value|
+----+----------+-+-----+
|date|1984-04-01|2|-3 |
| |1984-04-02|2| 3 |
| |1984-04-03|2| 3 |
| |1984-04-04|2|-5 |
+----+----------+-+-----+