as.integer() 在 int64 数据帧上产生意外结果
as.integer() on an int64 dataframe produces unexpected result
我在审查一些代码时遇到了这个奇怪的结果。如果你有一个数据帧,其中一个值为整数类型,并将其强制为整数,你会得到我认为你期望的结果:
library(dplyr)
tibble(x = as.integer(c(1))) %>% as.integer()
[1] 1
但是如果它是 int64 类型,你会得到一些奇怪的东西:
library(bit64)
tibble(x = as.integer64(c(1))) %>% as.integer()
[1] 0
什么给?我认为它与 int64
class 有关。但为什么我会得到零呢?这只是糟糕的错误处理吗?
更新
好的,当您在 int64
数据帧上调用 dput
时,会提示发生了什么:
structure(list(x = structure(4.94065645841247e-324,
class = "integer64")),
row.names = c(NA, -1L),
class = c("tbl_df", "tbl", "data.frame"))
所以 as.integer()
正确地将 4.94065645841247e-324 转换为零。但是为什么那是存储在 DF 中的内容?
此外,为了证明这不是 bit64
问题,我从数据库中得到的实际 df 得到了一个非常相似的结构:
structure(list(max = structure(2.78554211125295e-320,
class = "integer64")),
class = "data.frame",
row.names = c(NA, -1L))
我认为这是 bit64
的限制。 bit64
使用 S3 方法 as.integer.integer64
将 int64 转换为 int,但仅限于向量(不同于可应用于其他对象的基数 as.integer)。基数 as.integer
不知道如何在 data.frame 或其他情况下将 int64 转换为 int。
因此在加载 bit64
之后,as.integer
将在所有 int64 向量上实际调用 as.integer.integer64
,但不会在 data.frame 或 tibble 上调用。
我在审查一些代码时遇到了这个奇怪的结果。如果你有一个数据帧,其中一个值为整数类型,并将其强制为整数,你会得到我认为你期望的结果:
library(dplyr)
tibble(x = as.integer(c(1))) %>% as.integer()
[1] 1
但是如果它是 int64 类型,你会得到一些奇怪的东西:
library(bit64)
tibble(x = as.integer64(c(1))) %>% as.integer()
[1] 0
什么给?我认为它与 int64
class 有关。但为什么我会得到零呢?这只是糟糕的错误处理吗?
更新
好的,当您在 int64
数据帧上调用 dput
时,会提示发生了什么:
structure(list(x = structure(4.94065645841247e-324,
class = "integer64")),
row.names = c(NA, -1L),
class = c("tbl_df", "tbl", "data.frame"))
所以 as.integer()
正确地将 4.94065645841247e-324 转换为零。但是为什么那是存储在 DF 中的内容?
此外,为了证明这不是 bit64
问题,我从数据库中得到的实际 df 得到了一个非常相似的结构:
structure(list(max = structure(2.78554211125295e-320,
class = "integer64")),
class = "data.frame",
row.names = c(NA, -1L))
我认为这是 bit64
的限制。 bit64
使用 S3 方法 as.integer.integer64
将 int64 转换为 int,但仅限于向量(不同于可应用于其他对象的基数 as.integer)。基数 as.integer
不知道如何在 data.frame 或其他情况下将 int64 转换为 int。
因此在加载 bit64
之后,as.integer
将在所有 int64 向量上实际调用 as.integer.integer64
,但不会在 data.frame 或 tibble 上调用。