x <- 1:10
str(x)
# int [1:10] 1 2 3 4 5 6 7 8 9 10
str(as.double(x))
# num [1:10] 1 2 3 4 5 6 7 8 9 10
str(as(x, 'double'))
# int [1:10] 1 2 3 4 5 6 7 8 9 10
如果R中存在一个像类型转换这样基本的错误,我会感到惊讶。是否存在这种不一致的原因?
as
是用来强迫一个新的class
,从技术上来说,双重并不是一个class
而是一个storage.mode
。
y <- x
storage.mode(y) <- "double"
identical(x,y)
[1] FALSE
> identical(as.double(x),y)
[1] TRUE
该参数"double"
由特殊情况处理as
,并将尝试强制转换numeric
为该类integer
已继承的类,因此没有变化。
is.numeric(x)
[1] TRUE
没那么快...
尽管上述解释是合理的,但还有一些进一步的困惑。来自?double
:
从历史上看,R的浮点向量有两个名称,即double和numeric(以前是实数)。
double是类型的名称。numeric是模式的名称,也是隐式类的名称。作为S4正式类,请使用“数字”。
潜在的混淆是R使用模式“数字”来表示“双精度或整数”,这与S4的用法相冲突。因此,is.numeric测试模式,而不是类,而是测试as.numeric(与as.double相同)强制到该类。
因此,as
应x
根据文档确实进行更改...我将作进一步调查。
该地块比鲜奶油和玉米粉汤厚。
好吧,如果您debug
as
发现了最终发生的情况,那么将创建以下方法,而不是对coerce
将调用的泛型使用c(“ ANY”,“ numeric”)签名as.numeric
:
function (from, strict = TRUE)
if (strict) {
class(from) <- "numeric"
from
} else from
因此,实际上,class<-
被调用了x
,这最终意味着R_set_class
从被调用coerce.c
。我相信函数的以下部分决定了行为:
...
else if(!strcmp("numeric", valueString)) {
setAttrib(obj, R_ClassSymbol, R_NilValue);
if(IS_S4_OBJECT(obj)) /* NULL class is only valid for S3 objects */
do_unsetS4(obj, value);
switch(TYPEOF(obj)) {
case INTSXP: case REALSXP: break;
default: PROTECT(obj = coerceVector(obj, REALSXP));
nProtect++;
}
...
请注意switch语句:在整数和实数值的情况下,它不进行强制转换而出现。
有没有bug?
这是否是错误取决于您的观点。整数在某种意义上是数字,可以通过is.numeric(x)
return确认TRUE
,但严格来说,它们不是数字类。另一方面,由于整数被提升为在溢出时自动加倍,因此从概念上讲它们可能是相同的。有两个主要区别:i)整数需要较少的存储空间-这对于较大的向量可能是重要的,并且ii)与类型代码转换成本较高的外部代码进行交互时可能会起作用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句