将因子转换为数字的背后发生了什么?

What's happening behind the conversion of factor to numeric?

这里是小data.frame

e = data.frame(A=c(letters[1:5], 1:5))

我对执行以下命令时发生的事情感到有点困惑:

unclass(e$A) %>% as.numeric()

我得到以下输出:

 [1]  6  7  8  9 10  1  2  3  4  5

为什么 a:e 被视为 6:10

data.frame 是一个因素,这可以通过使用 str(e):

看出
'data.frame': 10 obs. of  1 variable:
 $ A: Factor w/ 10 levels "1","2","3","4",..: 6 7 8 9 10 1 2 3 4 5

这个因素有不同的水平,按字母顺序排列(其中 R 将数字排在字母之前),levels(e$A):

 [1] "1" "2" "3" "4" "5" "a" "b" "c" "d" "e"

as.numeric 将因子转换为级别的索引,即第一级获得值 1(这意味着 1 仍然是 1),第六级获得值 6(这意味着 "a" 变为6).

在这种情况下,您实际上已经使用 unclass() 强制执行此转换,这会生成您看到的数字向量。 as.numeric 然后只会删除 levels 属性。

?Comparison 告诉我们字符向量之间的任何比较(例如 sorting 它们)都是基于当前语言环境的整理顺序。

注意:这独立于 %>%

你的问题提出了一个深藏于每一种计算机语言核心的问题。就是字符排列顺序的问题。

R 帮助文件 ?sort 是这样说的:

The sort order for character vectors will depend on the collating sequence of the locale in use: see Comparison. The sort order for factors is the order of their levels

所以你可以尝试找到你的语言环境。您还需要检查定义国际字符串排序和比较规则的 ISO 14651 标准。 根据您所在的位置,您可能会发现订购非常特殊的字符的差异,但关于数字,我想它们总是排在第一位。

"a">"1"
#### [1] TRUE
"a">"A"
#### [1] FALSE

编辑: 关于大写和小写之间的字母顺序,它确实取决于您的系统语言环境(英语遵循 us_en 非英语语言环境可以遵循 ASCII 或其他参见此 wikipedia paragraph)。试试这个:

Sys.setlocale("LC_COLLATE", "C")
sort(c(1,2,3,"a", "b", "c", "A", "B", "C"))
#### [1] "1" "2" "3" "A" "B" "C" "a" "b" "c"
Sys.setlocale("LC_COLLATE", "French_France.1252")
sort(c(1,2,3,"a", "b", "c", "A", "B", "C"))
#### [1] "1" "2" "3" "a" "A" "b" "B" "c" "C"

类似的问题实际上已经在另一个So question

中讨论过