当前位置: 动力学知识库 > 问答 > 编程问答 >

r - Why is.vector on a data-frame doesn't return TRUE?

问题描述:

tl;dr - What the hell is a vector in R?

Long version:

Lots of stuff is a vector in R. For instance, a number is a numeric vector of length 1:

is.vector(1)

[1] TRUE

A list is also a vector.

is.vector(list(1))

[1] TRUE

OK, so a list is a vector. And a data frame is a list, apparently.

is.list(data.frame(x=1))

[1] TRUE

But, (seemingly violating the transitive property), a data frame is not a vector, even though a dataframe is a list, and a list is a vector. EDIT: It is a vector, it just has additional attributes, which leads to this behavior. See accepted answer below.

is.vector(data.frame(x=1))

[1] FALSE

How can this be?

网友答案:

Illustrating what @joran pointed out, that is.vector returns false on a vector which has any attributes other than names (I never knew that) ...

# 1) Example of when a vector stops being a vector...
> dubious = 7:11
> attributes(dubious)
NULL
> is.vector(dubious)
[1] TRUE

#now assign some additional attributes        
> attributes(dubious) <- list(a = 1:5)
> attributes(dubious)
$a
[1] 1 2 3 4 5

> is.vector(dubious)
[1] FALSE


# 2) Example of how to strip a dataframe of attributes so it looks like a true vector ...

> df = data.frame()
> attributes(df)
$names
character(0)

$row.names
integer(0)

$class
[1] "data.frame"

> attributes(df)[['row.names']] <- NULL
> attributes(df)[['class']] <- NULL
> attributes(df)
$names
character(0)

> is.vector(df)
[1] TRUE
网友答案:

To answer your question another way, the R Internals manual lists R's eight built-in vector types: "logical", "numeric", "character", "list", "complex", "raw", "integer", and "expression".

To test whether the non-attribute part of an object is really one of those vector types "underneath it all", you can examine the results of is(), like this:

isVector <- function(X) "vector" %in% is(X)

df <- data.frame(a=1:4)
isVector(df)
# [1] TRUE

# Use isVector() to examine a number of other vector and non-vector objects    
la  <- structure(list(1:4), mycomment="nothing")
chr <- "word"                  ## STRSXP
lst <- list(1:4)               ## VECSXP
exp <- expression(rnorm(99))   ## EXPRSXP
rw  <- raw(44)                 ## RAWSXP
nm  <- as.name("x")            ## LANGSXP
pl  <- pairlist(b=5:8)         ## LISTSXP

sapply(list(df, la, chr, lst, exp, rw, nm, pl), isVector)
# [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
网友答案:

Not an answer, but here are some other interesting things that are definitely worth investigating. Some of this has to do with the way objects are stored in R.

One example:

If we set up a matrix of one element, that element being a list, we get the following. Even though it's a list, it can be stored in one element of the matrix.

> x <- matrix(list(1:5)) # we already know that list is also a vector
> x
#      [,1]     
# [1,] Integer,5

Now if we coerce x to a data frame, it's dimensions are still (1, 1)

> y <- as.data.frame(x)
> dim(y)
# [1] 1 1

Now, if we look at the first element of y, it's the data frame column,

> y[1]
#              V1
# 1 1, 2, 3, 4, 5

But if we look at the first column of, y, it's a list

> y[,1]
# [[1]]
# [1] 1 2 3 4 5

which is exactly the same as the first row of y.

> y[1,]
# [[1]]
# [1] 1 2 3 4 5

There are a lot of properties about R objects that are cool to investigate if you have the time.

分享给朋友:
您可能感兴趣的文章:
随机阅读: