Assuming this data frame (generated as in the Prasad record, but with set.seed for reproducibility):
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))
then we will look at seven solutions:
1) zoo can give us a one-line solution (not counting the library operator):
library(zoo) z <- with(read.zoo(DF, split = 2), A - B)
providing this zoo series:
> z 1984-04-01 1984-04-02 1984-04-03 1984-04-04 -3 3 3 -5
Also note that as.data.frame(z) or data.frame(time = time(z), value = coredata(z)) provides a data frame; however, you can leave it as an object of the zoo, as this is a time series, and other operations are more convenient for him in this form, for example. plot(z)
2) sqldf can also give one solution (except for calling 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 can be used as the basis for a solution based on sqldf solution:
> 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) the aggregate can be used in the same way as sqldf and tapply above (although a slightly different solution has already appeared, based also on 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 from the doBy package can provide another solution, although it needs to transform to help it:
> 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) a remix from a remix package can do this, but with transform especially nice conclusion:
> 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 the Hmisc package also has an excellent result:
> 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 | +----+----------+-+-----+