我不明白为什么向量的类是向量元素的类而不是向量本身.
vector <- c("la", "la", "la")
class(vector)
## [1] "character"
matrix <- matrix(1:6, ncol=3, nrow=2)
class(matrix)
## [1] "matrix"
Run Code Online (Sandbox Code Playgroud)
这就是我从中得到的.class主要用于面向对象的编程,R中还有其他函数可以为你提供对象的存储模式(参见?typeof或?mode).
看着 ?class
许多R对象都有一个class属性,一个字符向量给出了对象继承的类的名称.如果对象没有class属性,则它有一个隐式类,"matrix","array"或mode(x)的结果
它似乎class工作如下
它首先查找$class属性
如果没有,它通过检查属性(在a中不存在)来检查对象是否matrix具有array结构或结构$dimvector
2.1.如果$dim包含两个条目,则将其称为amatrix
2.2.如果$dim包含一个条目或两个以上的条目,它将称之为array
2.3.如果$dim长度为0,则进入下一步(mode)
$dim长度为0并且没有$class属性,则执行mode所以根据你的例子
mat <- matrix(rep("la", 3), ncol=1)
vec <- rep("la", 3)
attributes(vec)
# NULL
attributes(mat)
## $dim
## [1] 3 1
Run Code Online (Sandbox Code Playgroud)
所以你可以看到它vec不包含任何属性(参见?c或?as.vector解释)
所以在第一种情况下,class执行
attributes(vec)$class
# NULL
length(attributes(vec)$dim)
# 0
mode(vec)
## [1] "character"
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,它检查
attributes(mat)$class
# NULL
length(attributes(mat)$dim)
##[1] 2
Run Code Online (Sandbox Code Playgroud)
它看到该对象有两个维度,并在那里调用它 matrix
为了说明两者vec并mat具有相同的存储模式,您可以这样做
mode(vec)
## [1] "character"
mode(mat)
## [1] "character"
Run Code Online (Sandbox Code Playgroud)
例如,您还可以看到与数组相同的行为
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"
Run Code Online (Sandbox Code Playgroud)
因此,无论array和matrix不解析class属性.让我们检查一下,例如,做什么data.frame.
df <- data.frame(A = rep("la", 3))
class(df)
## [1] "data.frame"
Run Code Online (Sandbox Code Playgroud)
从哪里class拿走了它?
attributes(df)
# $names
# [1] "A"
#
# $row.names
# [1] 1 2 3
#
# $class
# [1] "data.frame"
Run Code Online (Sandbox Code Playgroud)
如您所见,data.fram设置$class属性,但这可以更改
attributes(df)$class <- NULL
class(df)
## [1] "list"
Run Code Online (Sandbox Code Playgroud)
为什么list?因为data.frame没有$dim属性(既不是$class一个,因为我们只是删除了它),因此class执行mode(df)
mode(df)
## [1] "list"
Run Code Online (Sandbox Code Playgroud)
最后,为了说明如何class工作,我们可以手动设置class我们想要的任何东西,看看它会给我们什么
mat <- structure(mat, class = "vector")
vec <- structure(vec, class = "vector")
class(mat)
## [1] "vector"
class(vec)
## [1] "vector"
Run Code Online (Sandbox Code Playgroud)
R需要知道您正在操作的对象的类,以便对该对象执行适当的方法调度.R中的原子数据类型是一个向量,没有标量这样的东西,即R认为单个整数是一个长度为一个向量; is.vector( 1L ).
为了分派正确的方法,R必须知道数据类型.当你的语言被隐式地矢量化并且一切都被设计为在向量上运行时,知道某些东西是一个向量并不是很多.
is.vector( list( NULL , NULL ) )
is.vector( NA )
is.vector( "a" )
is.vector( c( 1.0556 , 2L ) )
Run Code Online (Sandbox Code Playgroud)
所以,你可以采取的返回值class( 1L )是[1] "integer"要的意思是,我是由类型的原子向量integer.
尽管在引擎盖下a 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)
Run Code Online (Sandbox Code Playgroud)
您还应该注意,在确定对象的类之前,R将始终检查它是第一个向量,例如,is.matrix(x)在某个矩阵上运行的情况下x,R检查它是否是第一个向量,然后检查对于维度属性.如果维度属性是INTEGER数据类型为LENGTH2 的向量,则它满足该对象作为矩阵的条件(以下代码片段来自/ src/include /的Rinlinedfuns.h)
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"
Run Code Online (Sandbox Code Playgroud)