HOWTO · R

在 R 中将因子转换为数值

了解如何安全地将 R 因子转换为数值标签、区分因子代码与实际值,并处理无效标签。

本页内容

当因子 f 包含数值标签,而你需要将这些标签作为数值使用时,请使用 as.numeric(as.character(f))。直接调用 as.numeric(f) 返回的是因子的内部整数代码。只有在有意将这些代码作为类别 ID 使用时,直接转换才合适。

理解 as.numeric 对因子的返回值

R 因子包含整数代码和一组独立的字符型水平。代码按照排序后的顺序或显式指定的顺序指向各个水平;它们不一定是原始测量值。你可以使用 levels() 和 unclass() 检查这两部分。

as.numeric(f) 的输出是类似 2 1 2 3 的代码序列。这并不表示原始值是 2、1、2 和 3。当数据框把看似数值的列导入为因子时,这一区别非常重要。

将看似数值的因子标签转换为数值

先把因子转换为字符,再把标签转换为数值:

f <- factor(c("3", "2", "3", "4"))
values <- as.numeric(as.character(f))
values

如果已知因子的水平都是数值,as.numeric(levels(f))[f] 是一种高效的替代方法。两种方法恢复的都是标签,而不是内部代码。先转换为字符通常更易读,并且清楚地体现了两次转换。

小数和负数形式的数值标签也采用相同的处理方式。应在导入或数据清理步骤附近执行转换,并在将结果用于计算前使用 str() 或 class() 进行检查。

有意地为类别标签编码

如果标签表示类别,就不要把它们的代码当作测量值。需要稳定的 ID 时,请显式设置类别顺序:

grade <- factor(c("low", "high", "low"), levels = c("low", "high"))
codes <- as.numeric(grade)
codes

这里的 1 和 2 是类别代码,因为顺序是显式指定的。它们并不表示 high 是 low 的两倍。对于业务或模型特定的映射,带名称的查找向量更清晰:

grade <- c("low", "high", "low")
score <- c(low = 10, high = 20)[grade]
score

这样可以清楚显示每个数值的含义,同时避免依赖默认的因子水平顺序。

处理非数值标签、缺失值和警告

即使先转换为字符,也不能把任意标签转换为数值。非数值文本会变成 NA,R 会发出强制转换警告;原本缺失的值仍然保持缺失:

f <- factor(c("12.5", "oops", NA))
values <- as.numeric(as.character(f))
values
is.na(values)

应将意外出现的 NA 视为数据质量问题的信号。检查原始标签,必要时去除或规范化空白,并在分析前决定如何处理无效记录。不要在没有说明的情况下将它们替换为零。如果标签表示类别而不是数值,请使用显式映射或显式设置顺序的因子。

验证转换结果

在依赖结果之前,请检查源数据的类、因子水平、转换后的值以及任何警告。简要规则如下:

  • 对有意使用的因子代码使用 as.numeric(f);
  • 对数值标签使用 as.numeric(as.character(f));
  • 对类别使用显式顺序或带名称的映射;以及
  • 转换导入的文本后检查 NA 值。

现代 R 代码应明确指定导入类型或因子水平,而不是依赖过去关于字符串是否自动转换为因子的默认行为。通过这些检查,可以清楚了解每个数值结果的预期含义。