考虑一个具有超过 100.000 个元素的
numeric
类型的向量。在下面的示例中,它只是范围 1:500001:
n <- 500001
arr <- as.numeric(1:n)
以下
factor
调用序列会导致奇怪的行为:
首先调用
factor
,并将 levels
参数指定为与定义 arr
完全相同的范围。可以预见的是,结果变量恰好具有 n
水平:
> tmp <- factor(arr, levels=1:n)
> length(levels(tmp))
[1] 500001
现在再次调用
factor
获取之前的结果。结果是新值 tmp2
缺少其级别中的一些值:
> tmp2 <- factor(tmp)
> length(levels(tmp2))
[1] 499996
检查缺少哪些项目,我们发现它是每 100.000 个元素(在本例中,其值等于其索引):
> which(!levels(tmp) %in% levels(tmp2))
[1] 100000 200000 300000 400000 500000
减少
n
至 <=100.000 eliminates this unexpected behaviour. However, it occurs for any n
> 100.000。
> n <- 99999
> arr <- as.integer(1:n)
> tmp <- factor(arr)
> tmp2 <- factor(tmp)
> print(length(levels(tmp2)))
[1] 99999
> which(!levels(tmp) %in% levels(tmp2))
integer(0)
当
arr
向量具有 numeric
以外的类型时,也不会发生这种情况:
> n <- 500001
> arr <- as.integer(1:n)
> tmp <- factor(arr, levels=1:n)
> tmp2 <- factor(tmp)
> print(length(levels(tmp2)))
[1] 500001
最后,当第一次调用
levels
时未指定 factor()
参数时,不会出现此问题。
什么可能导致这种行为?在 R 4.3.2 中测试。
我认为这与精度有关。如果指定
arr <- as.integer(1:n)
,则 tmp
和 tmp2
之间将具有相同的级别
> n <- 500001
> arr <- as.integer(1:n)
> tmp <- factor(arr, levels = 1:n)
> tmp2 <- factor(tmp)
> str(tmp)
Factor w/ 500001 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
> str(tmp2)
Factor w/ 500001 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...