Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
474 views
in Technique[技术] by (71.8m points)

r - Why is the class of a vector the class of the elements of the vector and not vector itself?

I don't understand why the class of a vector is the class of the elements of the vector and not vector itself.

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

matrix <- matrix(1:6, ncol=3, nrow=2)
class(matrix) 
## [1] "matrix"
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is what I get from this. class is mainly meant for object oriented programming and there are other functions in R which will give you the storage mod of an object (see ?typeof or ?mode).

When looking at ?class

Many R objects have a class attribute, a character vector giving the names of the classes from which the object inherits. If the object does not have a class attribute, it has an implicit class, "matrix", "array" or the result of mode(x)

It seems like class works as follows

  1. It first looks for a $class attribute

  2. If there isn't any, it checks if the object has a matrix or an array structure by checking the $dim attribute (which is not present in a vector)

    2.1. if $dim contains two entries, it will call it a matrix

    2.2. if $dim contains one entry or more than two entries, it will call it an array

    2.3. if $dim is of length 0, it goes to the next step (mode)

  3. if $dim is of length 0 and there is no $class attribute, it performs mode

So per your example

mat <- matrix(rep("la", 3), ncol=1)
vec <- rep("la", 3)
attributes(vec)
# NULL
attributes(mat)
## $dim
## [1] 3 1

So you can see that vec doesn't contain any attributes whatsoever (see ?c or ?as.vector for explanation)

So in first case, class performs

attributes(vec)$class
# NULL
length(attributes(vec)$dim)
# 0
mode(vec)
## [1] "character"

In the second case it checks

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

It sees that the object has two dimensions and there for calls it matrix

In order to illustrate that both vec and mat have same storage mode, you can do

mode(vec)
## [1] "character"
mode(mat)
## [1] "character"

You can also see, for example, same behavior with an array

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"

So both array and matrix don't parse a class attribute. Let's check, for example, what data.frame does.

df <- data.frame(A = rep("la", 3))
class(df)
## [1] "data.frame"

Where did class took it from?

attributes(df)    
# $names
# [1] "A"
# 
# $row.names
# [1] 1 2 3
# 
# $class
# [1] "data.frame"

As you can see, data.fram sets a $class attribute, but this could be changed

attributes(df)$class <- NULL
class(df)
## [1] "list"

Why list? Because data.frame don't have a $dim attribute (neither a $class one, because we just deleted it), thus class performs mode(df)

mode(df)
## [1] "list"

Lastly, in order to illustrate how class works, we can manually set the class to whatever we want and see what it will give us back

mat <- structure(mat, class = "vector")
vec <- structure(vec, class = "vector")
class(mat)
## [1] "vector"
class(vec)
## [1] "vector"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...