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

R as(x,';double';)和as.double(x)不一致 x,r,R,作为(x,“双”): 方法是预定义的,用于将任何对象强制转换为基本数据类型之一。例如,as(x,“numeric”)使用现有的as.numeric函数。这些内置方法可以通过showMethods(“强制”)列出。 这些函数管理允许将对象强制到的关系 给定的类 双精度(x): as.double是一个泛型函数。它与as.numeric相同。方法应返回基类型为“double”的对象。as.double创建、强制或测试双精度向量。as用于强制到新的类,从技术上讲,double不是类,而是存储.mode

作为(x,“双”): 方法是预定义的,用于将任何对象强制转换为基本数据类型之一。例如,as(x,“numeric”)使用现有的as.numeric函数。这些内置方法可以通过showMethods(“强制”)列出。 这些函数管理允许将对象强制到的关系 给定的类

双精度(x)
as.double是一个泛型函数。它与as.numeric相同。方法应返回基类型为“double”的对象。as.double创建、强制或测试双精度向量。

as
用于强制到新的
,从技术上讲,double不是
,而是
存储.mode

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的浮点值有两个名称,这是历史上的一个反常现象 向量,双精度和数字(以前有实数)

double是类型的名称。numeric是模式的名称,并且 也是隐式类的。作为S4正式类,使用“数值”

潜在的混乱是R使用了模式“数值”来表示 “double或integer”,与S4用法冲突。因此 is.numeric测试模式,而不是类,而是as.numeric(即 与as.double相同)强制类

因此,根据文档,
as
应该真正改变
x
。。。我会进一步调查

这块地比鲜奶油和玉米面汤还厚……

好的,如果您将
调试
,您会发现最终会创建以下方法,而不是对
强制
泛型使用c(“ANY”,“numeric”)签名,后者将调用
为.numeric

is.numeric(x)
[1] TRUE
注意switch语句:对于整数和实值,它在不进行强制的情况下爆发

是否存在Bug?


这是否是一个bug取决于您的观点。整数在某种意义上是数值的,正如
is.numeric(x)
返回
TRUE
所确认的,但严格来说,它们不是数值类。另一方面,由于整数在溢出时会自动升级为双精度,人们可能会从概念上认为它们是相同的。有两个主要区别:i)整数需要更少的存储空间-这对于更大的向量可能非常重要,以及ii)当与具有更大类型规程转换成本的外部代码交互时,可能会发挥作用。

相关:
类(x);类(x)
?numeric
名称注释部分可能与投票有关投票:如果你认为这是一个bug,请在这里投票。投票:如果你认为这不是bug,请在这里投票。@rawr很高兴看到我的R-devel帖子,这篇帖子值得等待;)不对
as(x,“numeric”)
使用由签名
c(“integer”,“numeric”)
发送的
S4方法,该签名不是
as.numeric()
。在r控制台中键入help(as)并阅读“References”之前的段落。……好的,要点。我所说的适用于类
“integer”
的对象,但对于所有其他类的对象,带有签名
c(“ANY”,“numeric”)
的方法将被调度,按照文档中的说明执行。(一定要看看同一段中推荐的
showMethods(“强制”)
,看看为什么
“integer”
类对象会受到不同的对待。)你能对joran的第一条注释给出一些见解吗?该注释没有使用“double”,但似乎是相关的<所以,这就是为什么
类(如(1L,“数字”)
不起作用的原因吗?例如,我在?@Frank中的“失败方法”
class(x)@Frank很有趣,因为整数已经是数字了。这并不是真正需要担心的事情,因为在R中溢出时整数将被提升为双倍。整数的存储效率更高,C/Fortran代码可能需要整数,但在其他方面可以认为是等效的。@James感谢您的解释!这是否意味着我的推理/方法是合理的?我可以使用
as(x,'classname')
x
转换为类(如果方法可用),并且当出现类似
“integer”
这样的异常而不是
“numeric”
时,这是可以的,因为该异常是在需要时由于一致的升级而导致的。显然,这种区别在某些条件下仍然很重要,意识到这一点很好。
is.numeric(x)
[1] TRUE
function (from, strict = TRUE) 
if (strict) {
    class(from) <- "numeric"
    from
} else from
...
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++;
    }
...