因素

factor 的对象是具有特定特征集的向量。

  1. 它在内部存储为 integer 向量。
  2. 它维护一个 levels 属性,显示值的字符表示。
  3. 它的类存储为 factor

为了说明,让我们从一组颜色生成 1,000 个观测值的向量。

set.seed(1)
Color <- sample(x = c("Red", "Blue", "Green", "Yellow"), 
                size = 1000, 
                replace = TRUE)
Color <- factor(Color)

我们可以观察上面列出的 Color 的每个特征:

#* 1. It is stored internally as an `integer` vector
typeof(Color)
[1] "integer"
#* 2. It maintains a `levels` attribute the shows the character representation of the values.
#* 3. Its class is stored as `factor`
attributes(Color)
$levels
[1] "Blue"   "Green"  "Red"    "Yellow"

$class
[1] "factor"

因子对象的主要优点是数据存储的效率。整数比字符需要更少的内存来存储。当许多计算机的资源比现有机器更有限时,这种效率是非常可取的(有关使用因素背后动机的更详细历史,请参阅 stringsAsFactors:未经授权的传记 )。即使在我们的 Color 对象中,也可以看到内存使用的差异。如你所见,将 Color 存储为字符所需的内存大约是因子对象的 1.7 倍。

#* Amount of memory required to store Color as a factor.
object.size(Color)
4624 bytes
#* Amount of memory required to store Color as a character
object.size(as.character(Color))
8232 bytes

将整数映射到级别

虽然因子的内部计算将对象视为整数,但人类消费的期望表示是字符级别。例如,

head(Color)
[1] Blue   Blue   Green  Yellow Red    Yellow  
Levels: Blue Green Red Yellow

比人类更容易理解

head(as.numeric(Color))
[1] 1 1 2 4 3 4

R 如何将字符表示与内部整数值匹配的近似说明如下:

head(levels(Color)[as.numeric(Color)])
[1] "Blue"   "Blue"   "Green"  "Yellow" "Red"    "Yellow"

比较这些结果

head(Color)
[1] Blue   Blue   Green  Yellow Red    Yellow  
Levels: Blue Green Red Yellow

现代使用因素

在 2007 年,R 引入了字符的散列方法,减少了字符向量的内存负担(参考: stringsAsFactors:未经授权的传记 )。请注意,当我们确定字符需要的存储空间是因子的 1.7 倍时,这是在最新版本的 R 中计算的,这意味着在 2007 年之前,字符向量的内存使用更加沉重。

由于现代 R 中的散列方法和现代计算机中更大的存储器资源,存储字符值的存储效率问题已经减少到非常小的问题。在大多数情况下,R 社区中的主流态度是对特征向量的偏好。偏离因素的主要原因是

  1. 非结构化和/或松散控制的字符数据的增加
  2. 当用户忘记她正在处理因素而不是角色时,因素趋势不符合要求

在第一种情况下,将自由文本或开放响应字段存储为因子是没有意义的,因为不太可能存在允许每个级别多于一个观察的模式。或者,如果未仔细控制数据结构,则可以获得对应于相同类别的多个级别(例如蓝色蓝色蓝色)。在这种情况下,许多人更愿意在转换为因素之前将这些差异作为字符进行管理(如果完全转换)。

在第二种情况下,如果用户认为她正在使用角色向量,则某些方法可能无法按预期进行响应。在尝试调试脚本和代码时,这种基本理解可能会导致混淆和挫折。严格来说,这可能被认为是用户的错误,但大多数用户都乐于避免使用因素并完全避免这些情况。