Reputation: 2710
I get this correct output running the code immediately beneath it, counting the number of times"A" appears in the Element column of the myData
data frame:
Element counted
1 A 4
Code for above output:
library(dplyr)
myData = data.frame(Element = c("A","A","C","A","B","B","A"),Class = c(0,0,0,0,1,1,2))
myData %>%
filter(Element == 'A') %>%
count(Element, name = 'counted')
However, I'd like to change the code so it returns the dataframe with count of 0 when it is run against a non-existing element. I need this for a series of ifelse(...)
statements that look back at that myData
dataframe. So, when running this code for an element D that doesn't exist:
myData %>%
filter(Element == 'D') %>%
count(Element, name = 'counted')
I'd like to get back:
Element counted
1 D 0
Instead of this which the code currently generates:
[1] Element counted
<0 rows> (or 0-length row.names)
In the complete code the D is an unknown, falling outside elements A - C. I'd like to return the 0 for any element outside A -C. I'd like to do this without including the element "D" in the factor levels.
Is there a slick way to this in dplyr
?
Upvotes: 3
Views: 449
Reputation: 35554
Convert Element
to factor
and give all levels you want, then set .drop = FALSE
in count()
:
myData %>%
mutate(Element = factor(Element, levels = c('A', 'B', 'C', 'D'))) %>%
count(Element, .drop = FALSE)
# Element n
# 1 A 4
# 2 B 2
# 3 C 1
# 4 D 0
It seens that you want to check whether a element is included in Element
. If it is, then count its amount; otherwise, print 0. You could assign elements you wan to check outside and use the following code:
x <- c('A', 'D')
myData %>%
filter(Element %in% x) %>%
mutate(Element = factor(Element, levels = x)) %>%
count(Element, .drop = FALSE)
# Element n
# 1 A 4
# 2 D 0
.drop
is actually an argument in group_by()
. This line
%>% count(Element, .drop = FALSE)
is equivalent to
%>% group_by(Element, .drop = FALSE) %>% tally()
under the hood. And tally
can also be traced back to summarise(n = n())
.
Upvotes: 4