提问人:Richie Cotton 提问时间:1/13/2015 最后编辑:Richie Cotton 更新时间:2/8/2022 访问量:12444
is 和 inherits 有什么区别?
What's the difference between is and inherits?
问:
如果我想检查变量是否继承自某个类,我可以使用 is
或 inherits
。
class(letters)
## [1] "character"
is(letters, "character")
## [1] TRUE
inherits(letters, "character")
## [1] TRUE
对于我应该使用哪一个,是否有偏好,它们是否返回不同的值?
答:
短版:
使用 ,但要小心数字和 S4 类。inherits
加长版:
在帮助页面的“另请参阅”部分:is
inherits 几乎总是等同于 is,无论是对于 S4 还是非 S4 对象,并且速度更快。非等同性适用于 具有条件超类的类,具有非平凡的 test= 在关系中(不常见且不鼓励):对于这些,是测试 关系,但根据定义继承,忽略条件 S4 对象的继承。
在帮助页面的“正式课程”部分:inherits
形式类的继承的类似物是 is。两个功能 行为一致,但有一个例外:S4 类可以有 条件继承,具有显式测试。在这种情况下,是将 测试条件,但 inherits 忽略所有条件超类。
因此,它们大多返回相同的内容,但速度更快,因此在大多数情况下,它应该是默认选择。(正如 Konrad 所提到的,还需要加载包,这可能使其不适合对性能敏感的 Rscript
使用。inherits
is
methods
如果您使用具有条件继承的 S4 类,则这些值可能会有所不同,但不建议这样做(请参阅“方法选择和调度:详细信息”部分),这意味着希望很少见。
这两个函数最明显的地方是检查整数是否为数字时。
class(1L)
## [1] "integer"
is.numeric(1L)
## [1] TRUE
is(1L, "numeric")
## [1] TRUE
inherits(1L, "numeric")
## [1] FALSE
评论
?class
If the object does not have a class attribute, it has an implicit class, ‘"matrix"’, ‘"array"’ or the result of ‘mode(x)’ (except that integer vectors have implicit class ‘"integer"’).
is
inherits
is
methods
Rscript
inherits
base
此外,我们还可以使用某种类型的对象进行测试。这三个函数可以返回不同的结果。根据这个答案,我做了以下工作is()
inherits()
is.*()
- 创建了大量不同类型的 R 对象
- 使用 、 和 提取了这些对象的类型。
storage.mode()
mode()
typeof()
class()
- 使用 和 测试对象是否属于返回类型。
is()
inherits()
is.*()
以下是上述三个步骤的一个小示例:
# Get object classes withs torage.mode(), mode(), typeof() and class().
obj <- logical()
(types <- c(storage.mode= storage.mode(obj),
mode= mode(obj),
type= typeof(obj),
class= class(obj)))
storage.mode mode type class
"double" "numeric" "double" "numeric"
# Test returned types with is, inhertis and is.*.
> is(obj, "double"); is(obj, "numeric")
[1] FALSE
[1] TRUE
> inherits(obj, "double"); inherits(obj, "numeric")
[1] FALSE
[1] TRUE
> is.double(obj); is.numeric(obj)
[1] TRUE
[1] TRUE
现在,我们使用以下代码对一堆对象类型执行此操作:
# Generate objects of different types.
library(xml2)
setClass("dummy", representation(x="numeric", y="numeric"))
obj <- list(
"logical vector" = logical(),
"integer vector" = integer(),
"numeric vector" = numeric(),
"complex vector" = complex(),
"character vector" = character(),
"raw vector" = raw(),
"factor" = factor(),
"logical matrix" = matrix(logical()),
"numeric matrix" = matrix(numeric()),
"logical array" = array(logical(8), c(2, 2, 2)),
"numeric array" = array(numeric(8), c(2, 2, 2)),
"list" = list(),
"pairlist" = .Options,
"data frame" = data.frame(),
"closure function" = identity,
"builtin function" = `+`,
"special function" = `if`,
"environment" = new.env(),
"null" = NULL,
"formula" = y ~ x,
"expression" = expression(),
"call" = call("identity"),
"name" = as.name("x"),
#"paren in expression" = expression((1))[[1]], # Code fails with this
#"brace in expression" = expression({1})[[1]], # Code fails with this
"S3 lm object" = lm(dist ~ speed, cars),
"S4 dummy object" = new("dummy", x = 1:10, y = rnorm(10)),
"external pointer" = read_xml("<foo><bar /></foo>")$node
)
# Extract types and test them.
res <- do.call("rbind.data.frame", Map(function(x, name){
types <- c(storage.mode= storage.mode(x),
mode= mode(x),
type= typeof(x),
class= class(x))
data.frame("object"= name,
"extract_method"= names(types),
"extract_result"= types,
"inherits"= sapply(types, function(i) inherits(x, i)),
"is"= sapply(types, function(i) is(x, i)),
"is.type"= sapply(types, function(i) eval(parse(text= paste0("tryCatch({is.", i, "(x)}, error= function(e){'is.", i, "() does not exist'})"))))
)}, obj, names(obj)))
rownames(res) <- 1:nrow(res)
res <- res[order(res$extract_method), ]
我们可以从结果中得到一些见解。例如,我们可以 loow were does not return same as :res
is.()
inherits()
> res[res$inherits != res$is, ]
object extract_method extract_result inherits is is.type
6 integer vector mode numeric FALSE TRUE TRUE
87 call storage.mode language FALSE TRUE TRUE
89 call type language FALSE TRUE TRUE
当然,结果显示的远不止这些,例如,我们可以看到三种提取方法之一的类型返回了哪里,等等。我把这个留在这里。事实上,我认为我的答案要广泛得多,因为它考虑了对象类型提取和测试的差异。在阅读了相当长的时间关于对象类型的文章后,我得出了上面的代码,并想分享它。但是,使用 soly 可以回答这个问题。inherits()
FALSE
res[res$inherits != res$is, ]
评论
"character" %in% class(letters)
is.list(iris)
TRUE
"list" %in% class(iris)
inherits(iris,"list")
FALSE
inherits