Why does dplyr/tibble not merge factors with different levels?

1,203 views
Skip to first unread message

Benoit Daloze

unread,
Oct 22, 2017, 12:18:34 PM10/22/17
to manipulatr
Hello,

This code:

a = data.frame(f=factor(c("a", "b")), g=c("a", "a"))
b = data.frame(f=factor(c("a", "c")), g=c("a", "a"))
a = a %>% group_by(g) %>% mutate(n=1)
b = b %>% group_by(g) %>% mutate(n=2)
rbind(a,b)
produces:

# A tibble: 4 x 3
# Groups:   g [1]
      f      g     n
  <chr> <fctr> <dbl>
1     a      a     1
2     b      a     1
3     a      a     2
4     c      a     2
Warning messages:
1: In bind_rows_(x, .id) : Unequal factor levels: coercing to character
2: In bind_rows_(x, .id) :
  binding character and factor vector, coercing into character vector
3: In bind_rows_(x, .id) :
  binding character and factor vector, coercing into character vector
What is the problem here? Could the factors not be trivially merged without any loss?

Using plain data.frame would merge the factor levels and produce no warnings.

Is there a reason for this rather strict behavior?

Best regards,
Benoit Daloze

Patrick Kilduff

unread,
Oct 23, 2017, 11:29:30 AM10/23/17
to Benoit Daloze, manipulatr
Hi Benoit,

This happens because R ‘assumes’ that a column of class factor in a data.frame has all possible levels. In your example, the “a” and “c” levels of “f” are in separate data.frames. Because R doesn’t understand all the possible levels in each data.frame (i.e., “a”, “b”, and “c”), but only the ones that are present, it converts the “f” column in each data.frame to class character before combining the two. Character vectors don’t have that restriction.

Converting to factors to character before “rbind”-ing or merging, will get around this warning message. If you need to recode the column to factor for your analysis, after combining the data you can do:

out <- rbind(a, b)
out$f <- as.factor(out$f)

More details can be found here: http://adv-r.had.co.nz/Data-structures.html

Good luck,
Patrick

--
You received this message because you are subscribed to the Google Groups "manipulatr" group.
To unsubscribe from this group and stop receiving emails from it, send an email to manipulatr+...@googlegroups.com.
To post to this group, send email to manip...@googlegroups.com.
Visit this group at https://groups.google.com/group/manipulatr.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages