NA_real_ 和 NaN 之间的区别

Yul*_*i S 24 r nan na

当我使用.Internal(inspect())toNA_real_和时NaN,它返回,

> .Internal(inspect(NA_real_))
@0x000001e79724d0e0 14 REALSXP g0c1 [REF(2)] (len=1, tl=0) nan
> .Internal(inspect(NaN))
@0x000001e797264a88 14 REALSXP g0c1 [REF(2)] (len=1, tl=0) nan
Run Code Online (Sandbox Code Playgroud)

看来它们唯一的区别是内存地址。

然而,当我将NA_real_and强制转换NaN为字符时,它会返回,

> as.character(c(NaN, NA_real_))
[1] "NaN" NA
Run Code Online (Sandbox Code Playgroud)

我知道它应该返回上述结果,因为NaN不能是字符,"NaN"并且它将NA_real被强制转换为NA_character_. 但考虑到他们的直觉是相同的,R 怎么会为他们返回不同的结果呢?

预先感谢您的任何建议!

Kon*_*lph 18

出色地。首先,请记住这NA是一个 R 概念,在 C 中没有对应的概念。因此,必然NA需要在 C 中以不同的方式表示。事实上,.Internal(inspect())不进行这种区分并不意味着它不是 xe2 x80\x99t 在其他地方制作。事实上,恰好.Internal(inspect())使用Rprintf打印 value\xe2\x80\x99s 内部双浮点表示。事实上,R NA 被编码为 C 浮点类型中的 NaN 值。

\n

其次,您观察到 \xe2\x80\x9c 他们唯一的区别是内存地址。\xe2\x80\x9d \xe2\x80\x94 那又怎样?至少从概念上来说,不同的内存地址足以区分 NA 和 NaN,不需要更多。

\n

但事实上,R 通过不同的途径来区分这些值。这是可能的,因为IEEE 754 双精度浮点格式多种不同的 NaN 表示形式,并且 R 为 NA 保留了一种特定的表示形式:

\n
static double R_ValueOfNA(void)\n{\n    /* The gcc shipping with Fedora 9 gets this wrong without\n     * the volatile declaration. Thanks to Marc Schwartz. */\n    volatile ieee_double x;\n    x.word[hw] = 0x7ff00000;\n    x.word[lw] = 1954;\n    return x.value;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

和:

\n
/* is a value known to be a NaN also an R NA? */\nint attribute_hidden R_NaN_is_R_NA(double x)\n{\n    ieee_double y;\n    y.value = x;\n    return (y.word[lw] == 1954);\n}\n\nint R_IsNA(double x)\n{\n    return isnan(x) && R_NaN_is_R_NA(x);\n}\n\nint R_IsNaN(double x)\n{\n    return isnan(x) && ! R_NaN_is_R_NA(x);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

( src/main/arithmetic.c)

\n

  • 文档中还值得一提的是:“使用 NA 进行数值计算通常会导致 NA:一个可能的例外是 NaN 也参与其中,在这种情况下可能会产生任何一个结果(这可能取决于 R 平台)。但是,这是不能保证,未来的 CPU 和/或编译器的行为可能会有所不同。” 这是因为 NA 中的 1954 年值不能保证在所有操作中都保留。 (3认同)

Hon*_*Ooi 9

NA是一个统计数据完整性概念:“缺失值”的概念。例如,如果您的数据来自填写表格的人员,则错误的条目或缺失的条目将被视为NA

NaN是一个数字计算概念:“不是数字”的东西。例如 0/0 是NAN,因为此计算的结果是未定义的(但请注意 1/0 是Inf,或无穷大,类似地 -1/0 是-Inf)。

R 在内部处理这些概念的方式不是您应该关心的事情。