Count occurrences of factor in R, with zero counts reported
Asked Answered
C

6

12

I want to count the number of occurrences of a factor in a data frame. For example, to count the number of events of a given type in the code below:

library(plyr)
events <- data.frame(type = c('A', 'A', 'B'),
                       quantity = c(1, 2, 1))
ddply(events, .(type), summarise, quantity = sum(quantity))

The output is the following:

     type quantity
1    A        3
2    B        1

However, what if I know that there are three types of events A, B and C, and I also want to see the count for C which is 0? In other words, I want the output to be:

     type quantity
1    A        3
2    B        1
3    C        0

How do I do this? It feels like there should be a function defined to do this somewhere.

The following are my two not-so-good ideas about how to go about this.

Idea #1: I know I could do this by using a for loop, but I know that it is widely said that if you are using a for loop in R, then you are doing something wrong, there must be a better way to do it.

Idea #2: Add dummy entries to the original data frame. This solution works but it feels like there should be a more elegant solution.

events <- data.frame(type = c('A', 'A', 'B'),
                       quantity = c(1, 2, 1))
events <- rbind(events, data.frame(type = 'C', quantity = 0))
ddply(events, .(type), summarise, quantity = sum(quantity))
Cutanddried answered 18/4, 2013 at 3:21 Comment(1)
e <- sapply(events, FUN=as.factor); table(e)Meijer
P
23

You get this for free if you define your events variable correctly as a factor with the desired three levels:

R> events <- data.frame(type = factor(c('A', 'A', 'B'), c('A','B','C')), 
+                       quantity = c(1, 2, 1))
R> events
  type quantity
1    A        1
2    A        2
3    B        1
R> table(events$type)

A B C 
2 1 0 
R> 

Simply calling table() on the factor already does the right thing, and ddply() can too if you tell it not to drop:

R> ddply(events, .(type), summarise, quantity = sum(quantity), .drop=FALSE)
  type quantity
1    A        3
2    B        1
3    C        0
R> 
Petite answered 18/4, 2013 at 3:29 Comment(0)
E
4
> xtabs(quantity~type, events)
type
A B C 
3 1 0 
Ethereal answered 18/4, 2013 at 3:41 Comment(2)
Doh, even better. Nice. Somehow I always forget about xtabs. But also needs the corrected factor variable I show.Petite
I only used the OP's data. There is an implicit sum in xtabs.Ethereal
I
2

Using dplyr library

library(dplyr)
data <- data.frame(level = c('A', 'A', 'B', 'B', 'B', 'C'),
                   value = c(1:6))

data %>%
  group_by(level) %>%
  summarize(count = n()) %>%
  View

If you choose also to perform mean, min, max operations, try this

data %>%
  group_by(level) %>%
  summarise(count = n(), Max_val = max(value), Min_val = min(value)) %>%
  View
Illumine answered 11/10, 2017 at 8:8 Comment(0)
B
0

Quite similar to @DWin's answer:

> aggregate(quantity~type, events, FUN=sum)
  type quantity
1    A        3
2    B        1
3    C        0
Beezer answered 18/4, 2013 at 3:45 Comment(2)
@DirkEddelbuettel Or his definition, with the dummy entries (what I actually used).Beezer
Which amounts to the same in a more convoluted way -- the char variable gets turned into a factor later by aggregate.Petite
R
0

In data you put your dataframe and into levels your categories.

table(factor(data, levels = 1:5)) 
Rockafellow answered 30/5, 2019 at 21:43 Comment(0)
P
0

Turn type column to factor and use count.

library(dplyr)
library(tidyr)

events %>% count(type = factor(type, c('A', 'B', 'C')), .drop = FALSE)

#  type n
#1    A 2
#2    B 1
#3    C 0

Another option is complete.

events %>%
  count(type) %>%
  complete(type = c('A', 'B', 'C'), fill = list(n = 0))
Persas answered 21/3, 2021 at 5:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.