为什么 type.convert 不将存储为数字的大"integers"转换为整数?


class(type.convert(as.numeric(1e3)))
# [1] "integer"
class(type.convert(as.numeric(1e4)))
# [1] "integer"
class(type.convert(as.numeric(1e5)))
# [1] "numeric"
class(type.convert(as.numeric(1e6)))
# [1] "numeric"

为什么较大的不转换为整数?还有很多事情要做:

.Machine$integer.max
# [1] 2147483647

也许答案可以在GitHub上typeconvert的C源代码中找到?不幸的是,我对C.非常陌生

好吧,这并不像看上去那么奇怪。让我们来看看utils:::type.convert.default:的源代码

function (x, na.strings = "NA", as.is = FALSE, dec = ".", numerals = c("allow.loss", 
"warn.loss", "no.loss"), ...) 
{
if (is.array(x)) 
storage.mode(x) <- "character"
else x <- as.character(x)
.External2(C_typeconvert, x, na.strings, as.is, dec, match.arg(numerals))
}

重要的部分是x <- as.character(x):无论输入是什么,它都会在尝试转换其类型之前被强制为一个字符(这很奇怪,因为numericinteger向量可能会按原样返回,而我认为无需进一步处理(。如何做到这一点,取决于x的性质和价值。例如:

#numeric value
as.character(100000)
#[1] "1e+05"
#integer value
as.character(100000L)
#[1] "100000"

当它尝试type.convert时,"100000"是一个合适的整数字符串,而"1e+05"不是,这解释了不同的行为。考虑as.character也取决于scipen选项。如果设置得足够高,as.character不会产生科学符号,而是一个可以被type.convert视为整数的数字。

options(scipen=999)
options("scipen")
as.character(100000)
#[1] "100000"

最新更新