Why Does Is.Vector() Return True for List

Why does is.vector() return TRUE for list?

A list is (in most cases) itself a vector. From the help files for ?list: "Most lists in R internally are Generic Vectors, whereas traditional dotted pair lists (as in LISP) are available but rarely seen by users (except as formals of functions)."

This means you can use vector to pre-allocate memory for a list:

x <- vector("list", 3)
class(x)
[1] "list"

Now allocate a value to the second element in the list:

x[[2]] <- 1:5

x

[[1]]
NULL

[[2]]
[1] 1 2 3 4 5

[[3]]
NULL

See ?list and ?vector for more details.

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

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

why the object is vector?

A vector in R is an ordered collection of stuff. Stuff in this case is

> mode(x1)
[1] "list"

from the help file

is.vector returns TRUE if x is a vector of the specified mode having no attributes other than names.

> attributes(x1)
$names
[1] "n1" "n2" "n3"

if we were to give x1 another attribute:

levels(x1)<-1:3

> x1
$n1
[1] 1

$n2
[1] 2

$n3
[1] 1 2 3 4 5

attr(,"levels")
[1] 1 2 3

> is.list(x1)
[1] TRUE

> is.vector(x1)
[1] FALSE

it would still be a list but not now a vector

From A brief history of S "The basic data structure in S is a vector of like­elements: numbers, character strings, or logical val­
ues. Although the notion of an attribute for an S object wasn't clearly implemented until the 1988 release,
from the beginning S recognized that the primary vector of data was often accompanied by other values that
described special properties of the data. For example, a matrix is just a vector of data along with an auxil­
iary vector named Dim that tells the dimensionality (number of rows and columns). Similarly, a time series
has a Tsp attribute to tell the start time, end time, and number of observations per cycle. These vectors
with attributes are known as vector structures, and this distinguishes S from most other systems."

Presumably it is similar in R which is an implementation of S so these vector structures are not designated as vectors.

Return TRUE/FALSE if common elements/no common elements between vectors

Another option:

vector1 <- c(1,2,3)
vector2 <- c(4,5,6,1)

any(Reduce(intersect, list(vector1, vector2)))

Output:

[1] TRUE

Why does is.recursive return TRUE for a function

A function actually is a recursive structure, I think just for safety reasons they decided not to provide a default method for the [[ function. You can get the more list-like representation with as.list()

str(as.list(mean))
# $ x : symbol
# $ ...: symbol
# $ : language UseMethod("mean")

So what you get is a list for your parameters and then the function body. If you want to get the body directly you can do

body(mean)
body(mean)[[1]]

and that does return the body as an expression that you can subset.

So functions are basically stored as lists of lists, therefore they are recursive.

Is everything a vector in R?

No, some things are not vectors in R, but most ways you would want to store data are vectors. Confusing the issue is that is.vector() has a weird definition: it doesn't allow attributes. For example,

x <- 1:3
is.vector(x)
#> [1] TRUE
attr(x, "foo") <- "bar"
x
#> [1] 1 2 3
#> attr(,"foo")
#> [1] "bar"
is.vector(x)
#> [1] FALSE

Created on 2021-09-07 by the reprex package (v2.0.0)

I would say that x is still a vector even with the attribute, but the is.vector() function thinks things with attributes aren't vectors. For a ridiculous example: according to is.vector(), factors aren't vectors, but you can treat them as if they are:

x <- factor(letters[1:4])
is.vector(x)
#> [1] FALSE
x
#> [1] a b c d
#> Levels: a b c d
x[2:3]
#> [1] b c
#> Levels: a b c d

Created on 2021-09-07 by the reprex package (v2.0.0)

So if we define vectors to be objects that can be indexed using [] or [[]], then most data types (types built from logical, integer, numeric, complex, character and raw, as well as lists) are vectors. There are no scalars of those types in R.

On the other hand, if you define vectors to be objects for which is.vector() returns TRUE, there are lots of data types that aren't vectors: factors, matrices, arrays, time series, data.frames, etc. So don't do that. :-)

Your examples using literals work that way because R doesn't treat literal values in any special way. They are just expressions that give objects.

Some things really aren't vectors: the NULL object, language objects like names (e.g. as.name("x")), environments, functions, etc.

What's the difference between a list and a vector whose mode is list?

I'd say they're the same:

identical(list(),vector(mode="list", length=0))
## [1] TRUE

(see also this question about the confusing fact that a list is a vector in R: usually when R users refer to "vectors", they actually mean atomic vectors ...)

In my experience the most common use case for vector(mode="list",...) is when you want to initialize a list with length>0. vector(mode="list",10) might be a little more expressive than replicate(10,NULL). If you want to create a length-0 list I can't see any reason to use vector() instead of list().



Related Topics



Leave a reply



Submit