当前位置:  开发笔记 > 编程语言 > 正文

as(x,'double')和as.double(x)不一致

如何解决《as(x,'double')和as.double(x)不一致》经验,为你挑选了1个好方法。

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)当与具有更大类型规则的外部代码交互时,转换成本可能会起作用.



1> James..:

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)当与具有更大类型规则的外部代码交互时,转换成本可能会起作用.


@Frank很有趣虽然`class(x)< - 'double''可行,但是,正如@James指出的那样,"double"不是一个类.
推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有