R语言:如何让函数返回因子级别而非其整数值?
解决ifelse返回因子整数而非因子本身的问题
这个问题我之前也碰到过!核心原因是ifelse()的特性——它会自动简化返回值的类型,当你传入因子对象时,它会提取因子的底层整数编码(也就是每个水平对应的数字),而不是保留因子类型,所以你的data$class才会变成int类型。
因为你没法用cut(),那咱们换几种靠谱的方法来实现:
方法1:先返回字符向量,再转换为因子
这是最简单直接的方式,先让函数返回字符类型的分类结果,之后再统一转成因子,还能灵活指定因子水平顺序:
data <- data.frame(a = 1:10) find_class <- function(i) { # 直接返回字符类型的分类 ifelse(i %in% c(1, 3, 5), 'A', ifelse(i %in% c(2, 4, 9), 'B', 'C')) } # 将结果转为因子,指定levels来保证顺序符合预期 data$class <- factor(find_class(data$a), levels = c('A', 'B', 'C'))
方法2:使用dplyr的case_when(可读性更高)
如果你习惯用tidyverse的工具,case_when()比嵌套ifelse更清晰,而且可以直接处理因子转换:
library(dplyr) data <- data.frame(a = 1:10) data <- data %>% mutate(class = factor( case_when( a %in% c(1, 3, 5) ~ 'A', a %in% c(2, 4, 9) ~ 'B', TRUE ~ 'C' # 剩下的情况都归为C ), levels = c('A', 'B', 'C') ))
方法3:用映射向量匹配(适合复杂分组规则)
如果你的分组规则以后可能变动,或者分组条件很多,用映射向量会更易于维护:
data <- data.frame(a = 1:10) # 创建值到分类的映射向量,键是原始数值,值是对应的分类 map_rules <- setNames( c(rep('A', 3), rep('B', 3), rep('C', 4)), c(1, 3, 5, 2, 4, 9, 6, 7, 8, 10) ) # 通过匹配映射向量得到分类,再转成因子 data$class <- factor(map_rules[as.character(data$a)], levels = c('A', 'B', 'C'))
小提醒
不管用哪种方法,记得在factor()里指定levels参数,这样可以保证因子的顺序是你想要的(比如A、B、C),不然R会默认按字母顺序排序哦。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

