Skip to content

Commit

Permalink
Add group_other option to fct_collapse, to allow for optional recodin…
Browse files Browse the repository at this point in the history
…g of all non-targeted levels into an "Other" category (#160)

Fixes #100
  • Loading branch information
AmeliaMN authored and hadley committed Jan 19, 2019
1 parent 2bd5f4c commit 22ad55b
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
@@ -1,6 +1,8 @@
# forcats 0.3.0.9000

* `fct_relabel()` now accepts character input.
* `fct_collapse()` gains a `group_other` argument to allow you to group all
un-named levels into `"Other"`. (#100, @AmeliaMN)

* `fct_cross()` creates a new factor containing the combined levels from two or more input factors, similar to `base::interaction` (@tslumley, #136)

Expand Down
11 changes: 9 additions & 2 deletions R/collapse.R
Expand Up @@ -3,6 +3,7 @@
#' @param .f A factor (or character vector).
#' @param ... A series of named character vectors. The levels in
#' each vector will be replaced with the name.
#' @param group_other Replace all levels not named in `...` with "Other"?
#' @export
#' @examples
#' fct_count(gss_cat$partyid)
Expand All @@ -15,10 +16,16 @@
#' dem = c("Not str democrat", "Strong democrat")
#' )
#' fct_count(partyid2)
fct_collapse <- function(.f, ...) {
fct_collapse <- function(.f, ..., group_other = FALSE) {
new <- rlang::dots_list(...)

levs <- as.list(unlist(new, use.names = FALSE))
if (group_other){
f <- check_factor(.f)
levels <- levels(f)
new[["Other"]] <- levels[!levels %in% levs]
levs <- levels
}

names(levs) <- names(new)[rep(seq_along(new), vapply(new, length, integer(1)))]

fct_recode(.f, !!!levs)
Expand Down
4 changes: 3 additions & 1 deletion man/fct_collapse.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions tests/testthat/test-collapse.R
Expand Up @@ -21,3 +21,17 @@ test_that("can collapse missing levels", {

expect_equal(f2, factor(c("x", "y")))
})

test_that("can collapse un-named levels to Other", {
f1 <- factor(letters[1:3])
f2 <- fct_collapse(f1, xy = c("a", "b"), group_other = TRUE)

expect_equal(f2, factor(c("xy", "xy", "Other"), levels = c("xy", "Other")))
})

test_that("does not automatically collapse unnamed levels to Other", {
f1 <- factor(letters[1:3])
f2 <- fct_collapse(f1, xy = c("a", "b"))

expect_equal(f2, factor(c("xy", "xy", "c"), levels = c("xy", "c")))
})

0 comments on commit 22ad55b

Please sign in to comment.