根据新因子字符串在列表中的位置,新的因子级别分配行为异常

new factor-level assignment behaves weirdly depending on the position of the new factor string in the list

我知道向 class factor 的对象添加新级别非常简单。但是,当我将要添加的因子水平放在列表的第一个位置时,对象(向量)中的实际值发生变化。

我说的是:

test <- factor(c("a", "a", "a", "b", "c", "a", "c", "b"))

test
#[1] a a a b c a c b
#Levels: a b c

levels(test)
#[1] "a" "b" "c"

## Works OK
levels(test) <- c(levels(test), "d")
#[1] a a a b c a c b
#Levels: a b c d

levels(test) <- c("d", levels(test))

## The values have changed
test
#[1] d d d a b d b a
#Levels: d a b c

我很好奇为什么新因子水平在列表中的位置会影响因子水平并且因子本身会被修改。

因子的水平是与基础整数值变量(枚举)关联的字符串。

如果我们检查这个变量的底层结构:

test <- factor(c("a", "a", "a", "b", "c", "a", "c", "b"))

我们看到:

str(test)
## Factor w/ 3 levels "a","b","c": 1 1 1 2 3 1 3 2

levels()所做的是将代码分配给整数值levels(test) <- c("d","a","b","c")使对应关系1 <-> "d" , 2 <-> "a", 3<-> "b", 4 <-> "c"。因此,具有基础值 1 的值(向量的第一个到第三个和第六个元素)现在具有关联标签 "d".

添加新级别的更安全方法是:

test <- factor(test,levels=c("d","a","b","c"))
test
## [1] a a a b c a c b
## Levels: d a b c
str(test)
## Factor w/ 4 levels "d","a","b","c": 2 2 2 3 4 2 4 3

这会改变级别的顺序(这对统计模型的绘图和参数化很重要),但它在分配整数值时使用字符值...