How can I keep NA when I change levels

后端 未结 2 1629
南旧
南旧 2021-01-23 06:03

I build a vector of factors containing NA.

my_vec <- factor(c(NA,\"a\",\"b\"),exclude=NULL)
levels(my_vec)
# [1] \"a\" \"b\" NA 

I change on

2条回答
  •  隐瞒了意图╮
    2021-01-23 07:03

    I finally created a function that first replaces the NA value with a temp one (inspired by @lmo), then does the replacement I wanted the standard way, then puts NA back in its place using @rawr's suggestion.

    my_vec <- factor(c(NA,"a","b1","b2"),levels = c("a",NA,"b1","b2"),exclude=NULL)
    my_vec <- level_sub(my_vec,c("b1","b2"),"c")
    my_vec
    # 1]  a    c    c   
    # Levels: a  c
    

    As a bonus level_sub can be used with na_rep = NULL which will remove the NA, and it will look good in pipe chains :).

    level_sub <- function(x,from,to,na_rep = "NA"){
      if(!is.null(na_rep)) {levels(x)[is.na(levels(x))] <- na_rep}
      levels(x)[levels(x) %in% from] <- to
      if(!is.null(na_rep)) {attr(x, 'levels')[levels(x) == na_rep] <- NA}
      x
    }
    

    Nevertheless it seems that R really doesn't want you to add NA to factors.

    levels(my_vec) <- c(NA,"a") will have a strange behavior but that doesn't stop here. While subset will keep NA levels in your columns, rbind will quietly remove them! I wouldn't be surprised if further investigation revealed that half R functions remove NA factors, making them very unsafe to work with...

提交回复
热议问题