为什么向量的类是向量元素的类而不是向量本身?

时间:2014-06-05 05:19:28

标签: r

我不明白为什么向量的类是向量元素的类而不是向量本身。

vector <- c("la", "la", "la")
class(vector) 
## [1] "character"

matrix <- matrix(1:6, ncol=3, nrow=2)
class(matrix) 
## [1] "matrix"

4 个答案:

答案 0 :(得分:8)

这就是我从中得到的。 class主要用于面向对象编程,R中还有其他函数可以为您提供对象的存储模式(请参阅?typeof?mode)。

查看?class

  

许多R对象都有一个class属性,一个给出的字符向量   对象继承的类的名称。如果是对象   没有class属性,它有一个隐式类,&#34; matrix&#34;,   &#34;阵列&#34;或模式(x)的结果

似乎class的工作方式如下

  1. 首先查找$class属性

  2. 如果没有,则通过检查matrix属性(在array属性中不存在,检查对象是否具有$dimvector结构一个$dim

    2.1。如果matrix包含两个条目,则会将其称为$dim

    2.2。如果array包含一个条目或两个以上的条目,则会将其称为$dim

    2.3。如果mode长度为0,则转到下一步($dim

  3. 如果$class长度为0且没有mode属性,则会执行mat <- matrix(rep("la", 3), ncol=1) vec <- rep("la", 3) attributes(vec) # NULL attributes(mat) ## $dim ## [1] 3 1
  4. 所以根据你的例子

    vec

    因此,您可以看到?c并未包含任何属性(请参阅?as.vectorclass以获取解释)

    因此,在第一种情况下,attributes(vec)$class # NULL length(attributes(vec)$dim) # 0 mode(vec) ## [1] "character" 执行

    attributes(mat)$class
    # NULL
    length(attributes(mat)$dim)
    ##[1] 2
    

    在第二种情况下,它会检查

    matrix

    它看到该对象有两个维度,并且可以调用它vec

    为了说明matmode(vec) ## [1] "character" mode(mat) ## [1] "character" 都具有相同的存储模式,您可以

    ar <- array(rep("la", 3), c(3, 1)) # two dimensional array
    class(ar)
    ##[1] "matrix"
    ar <- array(rep("la", 3), c(3, 1, 1)) # three dimensional array
    class(ar)
    ##[1] "array"
    

    例如,您还可以看到与数组相同的行为

    array

    因此,matrixclass都不会解析data.frame属性。我们来检查一下df <- data.frame(A = rep("la", 3)) class(df) ## [1] "data.frame" 的作用。

    class

    attributes(df) # $names # [1] "A" # # $row.names # [1] 1 2 3 # # $class # [1] "data.frame" 从哪里拿走了它?

    data.fram

    如您所见,$class设置了attributes(df)$class <- NULL class(df) ## [1] "list" 属性,但可以更改

    list

    为什么data.frame?由于$dim没有$class属性(class属性,因为我们刚刚将其删除),因此mode(df)执行mode(df) ## [1] "list"

    class

    最后,为了说明class的工作原理,我们可以手动将mat <- structure(mat, class = "vector") vec <- structure(vec, class = "vector") class(mat) ## [1] "vector" class(vec) ## [1] "vector" 设置为我们想要的任何内容,看看它会给我们带来什么

    {{1}}

答案 1 :(得分:6)

R需要知道您正在操作的对象的类,以便对该对象执行适当的方法调度。 R中的原子数据类型是一个向量,没有标量这样的东西,即R认为单个整数是一个长度为一个向量; is.vector( 1L )

为了分派正确的方法,R必须知道数据类型。当你的语言被隐式地矢量化并且所有被设计为在向量上运行时,知道某事物是向量的并不多。

is.vector( list( NULL , NULL ) )
is.vector( NA )
is.vector( "a" )
is.vector( c( 1.0556 , 2L ) )

因此,您可以将class( 1L )的返回值[1] "integer"表示,我是一个由integer 类型组成的原子向量。

尽管在引擎盖下matrix实际上只是一个具有两个维度属性的向量,但R必须知道它是一个矩阵,因此它可以在行的元素上逐行或按列操作。矩阵(或单独在任何单个下标元素上)。在子集化之后,您将返回矩阵中元素的数据类型的向量,这将允许R为您的数据分配适当的方法(例如,对字符向量或数字向量执行sort);

/* from the underlying C code in /src/main/subset.c....*/
result = allocVector(TYPEOF(x), (R_xlen_t) nrs * (R_xlen_t) ncs)

您还应该注意,在确定对象的类之前,R将始终检查它是否是第一个向量,例如如果在某个矩阵is.matrix(x)上运行x,R会检查它是否是第一个向量,然后检查维度属性。如果维度属性是INTEGER数据类型LENGTH 2的向量,则它满足该对象作为矩阵的条件(以下代码片段来自 Rinlinedfuns.h 来自/ SRC /包含/)

INLINE_FUN Rboolean isMatrix(SEXP s)
  495 {
  496     SEXP t;
  497     if (isVector(s)) {
  498    t = getAttrib(s, R_DimSymbol);
  499    /* You are not supposed to be able to assign a non-integer dim,
  500       although this might be possible by misuse of ATTRIB. */
  501    if (TYPEOF(t) == INTSXP && LENGTH(t) == 2)
  502        return TRUE;
  503     }
  504     return FALSE;
  505 }

#  e.g. create an array with height and width....  
a <- array( 1:4 , dim=c(2,2) )

#  this is a matrix!
class(a)
#[1] "matrix"

# And the class of the first column is an atomic vector of type integer....
class(a[,1])
[1] "integer"

答案 2 :(得分:4)

R language definition中,有六种基本类型的向量,其中一种是"character"。实际上没有基本的“矢量”类型,而是六种不同类型的矢量都是基类型。

另一方面,Matrix是一种数据结构。

答案 3 :(得分:2)

这是我发现的最好的图表,它列出了class函数使用的类层次结构:

rpy2 robjects package

虽然类名与R class函数的结果不完全对应,但我认为层次结构基本上是准确的。答案的关键是class函数仅提供层次结构中的根类

您会看到Vector 不是根类。您的示例的根类将是StrVector,它对应于"character"类,即具有字符元素的向量的类。相反,Matrix本身就是一个根类;因此,它的类是"matrix"