如何在创建factor时为未声明的非NA值分配默认层级与标签?
实现Factor未声明非NA值的默认层级映射
我之前用Stata,现在正在熟悉R的factor类型。想在指定factor的levels和labels时,把所有未声明的非NA值自动分配到一个默认层级/标签,同时保留原NA值不变。
现有示例代码:
library(dplyr) dt <- as.data.frame(mtcars) # 加载示例数据 dt$carb[4:6] <- NA # 手动设置几个NA值 dt <- dt %>% mutate( carb_f = factor(carb, levels = c(1,2,3,4), labels = c("One","Two","Three","Four") ) ) table(dt$carb, dt$carb_f, exclude=NULL)
现有运行结果:
One Two Three Four <NA> 1 5 0 0 0 0 2 0 9 0 0 0 3 0 0 3 0 0 4 0 0 0 10 0 6 0 0 0 0 1 8 0 0 0 0 1 <NA> 0 0 0 0 3
可以看到未声明的6和8被转为NA,但我希望把这类未声明的非NA值归到默认层级(比如标签"Unk"),得到如下结果:
One Two Three Four Unk <NA> 1 5 0 0 0 0 0 2 0 9 0 0 0 0 3 0 0 3 0 0 0 4 0 0 0 10 0 0 6 0 0 0 0 1 0 8 0 0 0 0 1 0 <NA> 0 0 0 0 0 3
不需要显式引用6和8这类未声明值,实现方法如下:
方法1:用dplyr的case_when预处理后转factor
先通过case_when把所有不在指定levels里的非NA值统一标记,再转为factor并指定labels:
library(dplyr) dt <- as.data.frame(mtcars) dt$carb[4:6] <- NA dt <- dt %>% mutate( carb_f = factor( case_when( carb %in% c(1,2,3,4) ~ as.character(carb), !is.na(carb) ~ "Unk", # 非NA且不在指定列表的归为Unk TRUE ~ NA_character_ # 保留原NA ), levels = c("1","2","3","4","Unk"), labels = c("One","Two","Three","Four","Unk") ) ) table(dt$carb, dt$carb_f, exclude=NULL)
运行后即可得到期望结果,无需知晓具体未声明值。
方法2:用forcats包的fct_other(更简洁)
forcats是tidyverse专门处理因子的工具包,fct_other可直接将除指定levels外的非NA值归为默认组:
library(dplyr) library(forcats) dt <- as.data.frame(mtcars) dt$carb[4:6] <- NA dt <- dt %>% mutate( carb_f = carb %>% factor(levels = c(1,2,3,4), labels = c("One","Two","Three","Four")) %>% fct_other(other_level = "Unk") # 将非指定levels的非NA值转为Unk ) table(dt$carb, dt$carb_f, exclude=NULL)
这个方法自动保留原NA值,仅把非NA的未声明值归到指定默认标签,完全不需要显式引用未声明的具体数值。
内容的提问来源于stack exchange,提问作者Warren Holroyd
相关产品推荐
相关产品推荐

