获取整数原子向量 (与数字向量对比)

3
我正在使用API获取一些不受我控制的字符数据,并从中创建一个data.frame。我希望结果变量能够尽可能自然地分类,而且操作最小。特别地,当适用时,我想要整数变量而不是数字变量。 我从XML数据中挖掘出这些数据,其中一个属性(称之为“attA”)将整数呈现为整数,即没有小数点和尾零。另一个属性(称为“attB”)更普遍和正确,但总是呈现带有一位小数的数字,即使它是统一为零。 (请注意,数据也可以是字符类型!) 我的初始方法基于“attA”并通过“type.convert()”进行处理,但现在我想使用“attB”。从阅读“type.convert()”文档中得知,当所有数据都可以表示为整数时,它并不生成整数。我是否理解错误?您有什么建议,可以在不惊天动地地处理字符数据的情况下获得我想要的结果吗?
attA <- c("1", "2")
str(type.convert(attA))
#>  int [1:2] 1 2

attB <- c("1.0", "2.0")
str(type.convert(attB))
#>  num [1:2] 1 2

unholy <- gsub("\\.0$", "", attB)
str(type.convert(unholy))
#>  int [1:2] 1 2

type.convert()文档中相关部分: "给定一个字符向量,它试图将其转换为逻辑、整数、数字或复数,如果失败,则将其转换为因子,除非as.is=TRUE。选择能够接受所有非缺失值的第一个类型... 包含可选空格后跟表示R整数或na.strings值的十进制常量的向量被转换为整数。"


1
你为什么不能用as.integer()替换type.convert()呢? as.integer(attB)效果很好。此外,可能可以使用read.table(),并在那里指定colClasses - Rich Scriven
一般来说,我不知道数据是否仅为整数、数字或字符。我真的希望逻辑、整数、数字、字符的层次结构能够被严格应用(我总是使用 type.convert(..., as.is = FALSE))。这就是为什么我不能使用 as.integer() 的原因。 - jennybryan
2个回答

2
从阅读type.convert()文档来看,当所有数据都可以表示为整数时,它没有产生整数值,这让我感到惊讶。我理解错了吗?
我认为你可能是理解错了。
在某些情况下,将写成123.0的数字转换为123确实会改变其含义:123.0中的末尾零可能意味着它代表比123(可能只测量到最接近的整数值)更高精度的值(例如,最接近十分之一)。因此,type.convert()采取适当/保守的方法,将123.0(以及123.)视为表示数值而不是整数值。
作为解决方案,可以尝试像这样的方法。
type.convert2 <- function(x) {
    x <- sub("(^\\d+)\\.0*$", "\\1", x)
    type.convert(x)
}

class(type.convert2("123.1"))
# [1] "numeric"
class(type.convert2("123.0"))
# [1] "integer"
class(type.convert2("123."))
# [1] "integer"

class(type.convert2("hello.0"))
# [1] "factor"
type.convert2("hello.0")
# [1] hello.0
# Levels: hello.0

1

一种方法是在将值强制转换为整数后进行测试,

res <- type.convert(attB)
if (isTRUE(all.equal((tmp <- as.integer(res)), res))) res <- tmp

另一种可能性是使用trunc来测试截断后的值。

type.convert不会将字符串转换为整数,因为它在C中使用strtol函数,该函数在“。”处停止。然后,在R源代码中,您可以看到,其中res是由strtol转换的字符串结果,

if (*endp != '\0') res = NA_INTEGER;

这意味着,如果整个字符串无效,则它不是一个整数。

感谢深入挖掘源代码!了解“.”的存在将对整数和数字产生何种影响非常有帮助。 - jennybryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接