R语言使用ifelse给diamonds数据集新增列时为何返回NA?
问题原因
你的代码返回NA、无法得到正确分类结果,核心存在3个错误:
ifelse()的第一个参数要求传入和数据集行数等长的逻辑判断向量(逐行返回TRUE/FALSE作为分支判断依据),但你传入的levels(diamonds$color)[4]只是一个长度为1的字符串,取值为"G"(即color变量的第4个水平),本身不包含任何逻辑判断。R运行时会尝试将这个字符串强制转换为逻辑值,而非"TRUE"/"FALSE"格式的字符串转逻辑值会直接返回NA,这就是结果中出现NA的直接原因。- 你写的判断逻辑完全没有关联数据集每一行的
color实际取值,哪怕传入的是合法的单值逻辑结果,也只会给所有行赋同一个固定值,根本没法实现按color水平逐行分类的需求。 - 原代码没有明确匹配水平和分类的对应规则,哪怕补全判断逻辑,也很容易出现good/bad归类错位的问题。
首先明确规则:diamonds数据集中的color是有序因子,水平从优到劣固定排序为D(最优)、E、F、G、H、I、J(最差),按需求最优3个水平D/E/F对应'good',剩余4个水平G/H/I/J对应'bad'。
修正方案
方法1:补全ifelse的逐行判断逻辑
用%in%运算符逐行判断当前行的color值是否落在前3个最优水平区间,再分别赋值即可:
library(tidyverse) diamonds %>% mutate( color2 = ifelse( color %in% levels(color)[1:3], "good", "bad" ) )
方法2:用forcats做因子水平合并(更推荐)
tidyverse内置的forcats包专门用于处理因子类型变量,可以直接对因子水平做归并,不需要写逐行判断逻辑,代码可读性更高、出错概率更低:
library(tidyverse) diamonds %>% mutate( color2 = fct_collapse( color, good = c("D", "E", "F"), bad = c("G", "H", "I", "J") ) )
内容的提问来源于stack exchange,提问作者Keith Duong
相关产品推荐
相关产品推荐

