This came up as an issue in tidyr (tidyverse/tidyr#1275, tidyverse/tidyr#1276).
library(forcats)
x <- factor(c(NA, "x"))
fct_unique(x)
#> [1] x
#> Levels: x
# Retains NA data at the end without adding a new factor level
x <- factor(c(NA, "x"))
tidyr:::fct_unique(x)
#> [1] x <NA>
#> Levels: x
# If an NA factor level already existed, doesn't change the level position
x <- factor(levels = c(NA, "x"), exclude = NULL)
tidyr:::fct_unique(x)
#> [1] <NA> x
#> Levels: <NA> x
We could use the tidyr implementation here:
fct_unique <- function(x) {
if (!is.factor(x)) {
abort("`x` must be a factor.")
}
levels <- levels(x)
out <- levels
if (!anyNA(levels) && anyNA(x)) {
out <- c(out, NA_character_)
}
factor(out, levels = levels, exclude = NULL, ordered = is.ordered(x))
}
This came up as an issue in tidyr (tidyverse/tidyr#1275, tidyverse/tidyr#1276).
We could use the tidyr implementation here: