3.5 检查和更改类
直接在命令提示符下,以交互的方式键入类class
的函数名来检查变量是很有用的。但是如果想在脚本中测试对象的类型,则最好用is
函数,或针对某个类写的特定函数。通常,我们会做这样的测试:
if(!is(x, "some_class"))
{
# 采取某些纠正措施
}
大部分的类都会有自己的is.*
函数。通常,直接调用它们比使用通用is
函数稍显高效。例如:
is.character("red lorry, yellow lorry")
## [1] TRUE
is.logical(FALSE)
## [1] TRUE
is.list(list(a = 1, b = 2))
## [1] TRUE
以下命令可查看在base
包中所有的is
函数:
ls(pattern = "^is", baseenv())
## [1] "is.array" "is.atomic"
## [3] "is.call" "is.character"
## [5] "is.complex" "is.data.frame"
## [7] "is.double" "is.element"
## [9] "is.environment" "is.expression"
## [11] "is.factor" "is.finite"
## [13] "is.function" "is.infinite"
## [15] "is.integer" "is.language"
## [17] "is.list" "is.loaded"
## [19] "is.logical" "is.matrix"
## [21] "is.na" "is.na.data.frame"
## [23] "is.na.numeric_version" "is.na.POSIXlt"
## [25] "is.na<-" "is.na<-.default"
## [27] "is.na<-.factor" "is.name"
## [29] "is.nan" "is.null"
## [31] "is.numeric" "is.numeric.Date"
## [33] "is.numeric.difftime" "is.numeric.POSIXt"
## [35] "is.numeric_version" "is.object"
## [37] "is.ordered" "is.package_version"
## [39] "is.pairlist" "is.primitive"
## [41] "is.qr" "is.R"
## [43] "is.raw" "is.recursive"
## [45] "is.single" "is.symbol"
## [47] "is.table" "is.unsorted"
## [49] "is.vector" "isatty"
## [51] "isBaseNamespace" "isdebugged"
## [53] "isIncomplete" "isNamespace"
## [55] "isOpen" "isRestart"
## [57] "isS4" "isSeekable"
## [59] "isSymmetric" "isSymmetric.matrix"
## [61] "isTRUE"
在上例中,ls
列出所有的变量名,"^is"
是一个正则表达式,它意味着“匹配所有以'is'开头的字符串”,而baseenv
函数则返回base
包中所有的环境。环境是相对高级的话题,将在第6章讨论,现在不用拘泥于它的含义。
assertive
包3含有更多is
函数,命名方式更加一致。
3 这个包是我写的。
有点奇怪的是,is.numeric
函数对整数和浮点数都返回TRUE
值。如果我们只测试浮点数,则须使用is.double
。然而,一般无需这么做,因为在R中浮点和整数几乎能互换使用。请注意,在下例中,在数字后面添加L
后缀就能把它转换为整数:
is.numeric(1)
## [1] TRUE
is.numeric(1L)
## [1] TRUE
is.integer(1)
## [1] FALSE
is.integer(1L)
## [1] TRUE
is.double(1)
## [1] TRUE
is.double(1L)
## [1] FALSE
有时候,我们想改变一个对象的类型。这就是所谓的转型(casting),大部分的is*
函数都有与之对应的as*
函数。尽可能使用特定的as*
函数而非单纯的as
函数,因为它们通常更有效,而且往往针对该类会有额外的逻辑。例如,当尝试把字符串转换为数字时,as.numeric
比单独的as
函数效率稍高,虽然两者皆可使用:
x <- "123.456"
as(x, "numeric")
## [1] 123.5
as.numeric(x)
## [1] 123.5
注意
R能打印到小数点后第几位取决于R的设置。你可以使用
options(digits=n)
来设置全局默认选项,其中n
在1和22之间。第7章将再讨论如何控制打印数字。
然而,请注意在下例中,当一个向量被转换成一个数据框时(类似电子表格的数据变量),as
函数抛出一个错误:
y <- c(2, 12, 343, 34997) #请参考 http://oeis.org/A192892
as(y, "data.frame")
as.data.frame(y)
注意
一般情况下,特定类的变量的使用应始终优先于标准函数
as
。
尽管不推荐(见16.7节,类的分配另有用途),我们也可以直接给对象分配一个新的类以改变其类型:
x <- "123.456"
class(x) <- "numeric"
x
## [1] 123.5
is.numeric(x)
## [1] TRUE