【问题标题】:What is the difference between mode and class in R?R中的模式和类有什么区别?
【发布时间】:2020-05-28 04:40:58
【问题描述】:

我正在学习 R(我这周才开始学习),我一直在努力处理 typeof、mode、storage.mode 和 class 的概念。我一直在上下搜索(官方 R 文档、StackOverflow、Google 等),但我无法找到任何关于它们之间区别的明确解释。 (一些StackOverflowandCrossValidated的答案并没有真正帮助我弄清楚。)最后(我希望),我想我明白了,所以我的问题是验证我的理解是否正确。

mode vs storage.mode: mode and storage.mode are basically the same thing,除了“单一”数据类型的处理方式略有不同。

mode vs typeof: Very similar, except for a few differences, 最值得注意的是 (typeof "integer" and "double") = (mode "numeric");和两者 (typeof "special" 和 "builtin" = (mode "function")。

类:类基于 R 的面向对象的类层次结构。我很难找到这个图形布局,但我能找到的最好的是这个图表:

(如果有人能指出更准确的 R 类层次结构,我会替换它。)

虽然类名与 R class() 函数的结果并不完全对应,但我相信层次结构基本上是准确的。我的理解是对象的“类”——即class()函数的结果——是层次结构中的根类。所以,例如,“Vector”是不是根类,因此它永远不会显示为 class() 函数的结果。根类可能是“StrVector”(“字符”)或“BoolVector”(“逻辑”)。相反,“Matrix”本身就是一个根类;因此,它的类是“矩阵”。

显然,R 支持多重继承,因此有些对象可以有多个类。

typeof/mode/storage.mode vs class:这是我最难理解的部分。我现在的理解是:typeof/mode/storage.mode(我以后将简称为 “mode”)基本上是 R 对象可以作为其值之一保存的最复杂的数据类型 .因此,例如,由于矩阵、数组和向量只能保存一种向量数据类型,它们的模式(即它们可以保存的最复杂的数据类型)通常是数字、字符或逻辑,即使它们的类(它们在类中的位置层次结构)是完全不同的东西。

最有趣(即令人困惑)的地方在于列表之类的对象。 “列表”的模式意味着对象中的每个值本身都可以是一个列表(即可以保存多种数据类型的对象)。因此,无论类本身是否是“列表”,都有多个对象(例如数据框)可以包含不同的值,因此它们的模式是“列表”,即使它们的类是其他的。

所以,总而言之,我的理解是:

  • typeof/mode/storage.mode(几乎相同)基本上是 R 对象可以作为其值之一保存的最复杂的数据类型;而

  • 类是根据R类层次结构的对象面向对象的分类。

我的理解准确吗?如果不是,谁能给个更准确的解释?

【问题讨论】:

  • 所以你的类概念需要首先调整。没有 R 对象系统。 class 属性属于 S3 方法调度系统,但还有许多其他属性。您找到的图表描述了 R 语言中的一些基本数据类型结构,但这与面向对象的系统根本没有任何关系。
  • @Richard Scriven,如果我的理解是正确的,那么我正在寻找的答案很简单。但是,如果我的理解有误,那么我正在寻找的答案应该指出我的误解。所以,这不是一个简单的是/否。实际上,我考虑过回答我自己的问题(blog.stackoverflow.com/2011/07/…)的选项,但由于我不确定答案,我没有足够的胆量这样做。
  • @joran,您能否将该评论扩展为完整答案?这就是我要找的。​​span>

标签: r


【解决方案1】:

'mode' 是对象的互斥分类,根据 它们的基本结构。 “原子”模式是数字的、复杂的、 性格和逻辑。递归对象具有诸如“列表”或 “功能”或其他一些。一个对象只有一种模式。

'class' 是分配给对象的属性,用于确定通用性 函数与它一起运行。它不是相互排斥的 分类。如果一个对象没有分配给它特定的类,例如 作为一个简单的数值向量,它的类通常与其模式相同, 按照惯例。

更改对象的模式通常称为“强制”。的模式 对象可以更改而不必更改类。例如

> x <- 1:16
> mode(x)
[1] "numeric"
> dim(x) <- c(4,4)
> mode(x)
[1] "numeric"
> class(x)
[1] "matrix"
> is.numeric(x)
[1] TRUE
> mode(x) <- "character"
> mode(x)
[1] "character"
> class(x)
[1] "matrix"

但是:

> x <- factor(x)
> class(x)
[1] "factor"
> mode(x)
[1] "numeric"

在这个阶段,即使x 再次具有模式数字,它的新类, factor,禁止将其用于算术运算。

在实践中,mode 用的不多,除了定义一个类 当没有明确的类被分配时隐式的。

【讨论】:

    【解决方案2】:

    我希望以下示例对您有所帮助。尤其是最后两个例子。

    x <- 1L
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- 1
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- letters
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- TRUE
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- cars
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- cars[1]
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- cars[[1]]
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- matrix(cars)
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- new.env()
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- expression(1 + 1)
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- quote(y <- 1 + 1)
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    
    x <- ls
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    

    结果是:

    [1] "integer"      "numeric"      "integer"      "integer"
    [1] "numeric"      "numeric"      "double"       "double" 
    [1] "character"    "character"    "character"    "character"
    [1] "logical"      "logical"      "logical"      "logical"
    [1] "data.frame"   "list"         "list"         "list"      
    [1] "data.frame"   "list"         "list"         "list"      
    [1] "numeric"      "numeric"      "double"       "double" 
    [1] "matrix"       "list"         "list"         "list"  
    [1] "environment"  "environment"  "environment"  "environment"
    [1] "expression"   "expression"   "expression"   "expression"
    [1] "<-"           "call"         "language"     "language"
    [1] "function"     "function"     "function"     "closure" 
    

    最后一个示例向您展示了 typeof() != storage.mode() 的情况。

    【讨论】:

    • 谢谢。您能否以相同的方式为整数举例说明
    • 很好的解释和很好的代码来说明差异。这告诉我......大多数时候......对于内省或类型发现......使用class()typeof()函数。这些给了我对象类/类型信息和存储信息。 mode() 函数非常没用,因为 storage.mode() 细节(例如,双精度、整数)告诉我它是数字的。对我来说底线:1)首先使用class(),然后typeof() 来获取最相关的对象信息。我使用的是mode()
    【解决方案3】:

    只是为了更好的可读性。

    我希望以下示例对您有所帮助。尤其是最后两个例子。

    x <- 1L
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "integer"      "numeric"      "integer"      "integer"
    
    x <- 1
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "numeric"      "numeric"      "double"       "double" 
    
    x <- letters
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "character"    "character"    "character"    "character"
    
    x <- TRUE
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "logical"      "logical"      "logical"      "logical"
    
    x <- cars
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "data.frame"   "list"         "list"         "list"   
    
    x <- cars[1]
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "data.frame"   "list"         "list"         "list"      
    
    x <- cars[[1]]
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "numeric"      "numeric"      "double"       "double" 
    
    x <- matrix(cars)
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "matrix"       "list"         "list"         "list"  
    
    x <- new.env()
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "environment"  "environment"  "environment"  "environment"
    
    x <- expression(1 + 1)
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "expression"   "expression"   "expression"   "expression"
    
    x <- quote(y <- 1 + 1)
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "<-"           "call"         "language"     "language"
    
    x <- ls
    print(c(class(x), mode(x), storage.mode(x), typeof(x)))
    [1] "function"     "function"     "function"     "closure"
    

    致谢 - @SHUAICHENG WANG

    【讨论】:

      【解决方案4】:

      简单地说,真正有用的只有class()typeof()

      • class 可以被描述为对象的“容器”,该属性使该对象在外部通过以这种特定“类型”对象作为参数的函数进行操作

      • type 是这个对象在容器内的组成部分,底层值的“类型”

      好明显的例子:

      x <- as.Date('2010-01-01')
      class(x) # Date
      typeof(x) # double
      unclass(x) # 14610
      
      attr(x, 'tz') <- 'CEST'
      attributes(x)$class # "Date"
      attributes(x)$tz # "CEST"
      

      【讨论】:

        猜你喜欢
        • 2016-10-03
        • 1970-01-01
        • 1970-01-01
        • 2013-01-11
        • 2016-01-10
        • 1970-01-01
        • 2022-01-03
        • 2013-03-22
        相关资源
        最近更新 更多