Search code examples
rforcats

How to test the result of `fct_na_value_to_level()`?


The default behavior of fct_na_value_to_level() is to replace NAs with a non-character NA level.

I'm working on a function where I have to test if an object represents a missing value.

However, the result of this function seems very hard to test:

library(forcats)
library(dplyr)
letters[1:3] %>% factor %>% fct_na_value_to_level('x')
#> [1] a b c
#> Levels: a b c x
a = c("foo", "bar", NA) %>% fct_na_value_to_level()
a[3]
#> [1] <NA>
#> Levels: bar foo <NA>
a[3] %>% dput()
#> structure(3L, levels = c("bar", "foo", NA), class = "factor")
a[3] %>% is.na()
#> [1] FALSE
a[3]==NA
#> [1] NA
a[3]=="NA"
#> [1] FALSE

Created on 2024-08-12 with reprex v2.1.1

How am I supposed to test the result of fct_na_value_to_level()?


Solution

  • This is a factor variable where NA is considered a level. is.na(a) tests if the internal integers are NA but they aren't. Your output clearly shows a 3L.

    a <- factor(1:3, labels = c("bar", "foo", NA))
    is.na(a)
    #[1] FALSE FALSE FALSE
    

    You need to get the levels and test if they are NA.

    is.na(levels(a)[a])
    #[1] FALSE FALSE  TRUE 
    

    Or alternatively:

    unclass(a) == which(is.na(levels(a)))
    #[1] FALSE FALSE  TRUE
    

    You could wrap these in a function for convenience.