tl;dr - What the hell is a vector in R?
Lots of stuff is a vector in R. For instance, a number is a numeric vector of length 1:
A list is also a vector.
OK, so a list is a vector. And a data frame is a list, apparently.
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.
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)  TRUE #now assign some additional attributes > attributes(dubious) <- list(a = 1:5) > attributes(dubious) $a  1 2 3 4 5 > is.vector(dubious)  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  "data.frame" > attributes(df)[['row.names']] <- NULL > attributes(df)[['class']] <- NULL > attributes(df) $names character(0) > is.vector(df)  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) #  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) #  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.
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
Now, if we look at the first element of
y, it's the data frame column,
> y # V1 # 1 1, 2, 3, 4, 5
But if we look at the first column of,
y, it's a list
> y[,1] # [] #  1 2 3 4 5
which is exactly the same as the first row of
> y[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.