4

I have data frame:

station     date        classification
 1    June - 01/16          A
 2    June - 03/16          B
 1    June - 01/16          A
 7    June - 01/16          C
 1    June - 03/16          A
 2    June - 03/16          B
 2    June - 03/16          B

I want to get the total number of occurrences of A, B and C, aggregated by the station # and date:

For example, station 1 on June 01 has 2 As, while station 2 on June 3 has 3 Bs.

I tried,

aggregate(x = list(data_frame$classification), by = list(station=data_frame$station, Date=data_frame$date), function(x) length(unique(x))
Cybernetic
  • 12,628
  • 16
  • 93
  • 132
  • The `x` doesn't need to be a `list` – akrun Apr 18 '16 at 17:01
  • Okay, thank you. I still get an error. "not all arguments have the same length" – Cybernetic Apr 18 '16 at 17:03
  • I guess you want a `table` i.e `aggregate(classification~., data_frame, FUN= table)` because if you are using `length(unique(x))` then it will be all 1s. – akrun Apr 18 '16 at 17:05
  • Ah nice...so that worked when only doing it by station. Trying to aggregate it by both station and date is causing the problem. Can't you aggregate by more than one column? – Cybernetic Apr 18 '16 at 17:12
  • The `.` indicates all the other columns in the dataset. – akrun Apr 18 '16 at 17:14

3 Answers3

7

If we need the count of 'A', 'B' and 'C', it may be better to reshape. We convert the 'data.frame' to 'data.table' (setDT(data_frame)) and use dcast from data.table to reshape from 'long' to 'wide' format, specifying the fun.aggregate as length.

library(data.table)
dcast(setDT(data_frame), station+date~classification, length)
#   station         date A B C
#1:       1 June - 01/16 2 0 0
#2:       1 June - 03/16 1 0 0
#3:       2 June - 03/16 0 3 0
#4:       7 June - 01/16 0 0 1

A dplyr option is

library(dplyr)
data_frame %>%
        group_by(station, date, classification) %>%
        tally()
# station         date classification     n
#    (int)        (chr)          (chr) (int)
#1       1 June - 01/16              A     2
#2       1 June - 03/16              A     1
#3       2 June - 03/16              B     3
#4       7 June - 01/16              C     1

data

data_frame <- structure(list(station = c(1L, 2L, 1L, 7L, 1L, 2L, 2L), 
date = c("June - 01/16", 
"June - 03/16", "June - 01/16", "June - 01/16", "June - 03/16", 
"June - 03/16", "June - 03/16"), classification = c("A", "B", 
"A", "C", "A", "B", "B")), .Names = c("station", "date", "classification"
), class = "data.frame", row.names = c(NA, -7L))
akrun
  • 874,273
  • 37
  • 540
  • 662
1

The package plyr is great for this.

library(plyr) 
count(data_frame, c("classification", "station", "date")) 
shirewoman2
  • 1,842
  • 4
  • 19
  • 31
0

sql way.

sqldf("select station, date ,classification, count(classification) from x group by station, date ,classification")
Chirayu Chamoli
  • 2,076
  • 1
  • 17
  • 32