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是模式的名称,也是隐式类的名称.作为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语句:在整数和实数值的情况下,它不会强制执行.
错误与否?
这是否是一个错误取决于你的观点.在某种意义上,整数是数字的,通过is.numeric(x)
返回来确认TRUE
,但严格来说它们不是数字类.另一方面,由于整数在溢出时被提升为自动加倍,因此可以在概念上将它们视为相同.有两个主要区别:i)整数需要较少的存储空间 - 这对于较大的向量可能很重要,并且ii)当与具有更大类型规则的外部代码交互时,转换成本可能会起作用.
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是模式的名称,也是隐式类的名称.作为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语句:在整数和实数值的情况下,它不会强制执行.
错误与否?
这是否是一个错误取决于你的观点.在某种意义上,整数是数字的,通过is.numeric(x)
返回来确认TRUE
,但严格来说它们不是数字类.另一方面,由于整数在溢出时被提升为自动加倍,因此可以在概念上将它们视为相同.有两个主要区别:i)整数需要较少的存储空间 - 这对于较大的向量可能很重要,并且ii)当与具有更大类型规则的外部代码交互时,转换成本可能会起作用.