how to create a list in R from two vectors (one would be the keys, the other the values)?
If your values are all scalars, then there's nothing wrong with having a "key-value store" that's just a vector.
vals <- 1:1000000
keys <- paste0("key", 1:1000000)
names(vals) <- keys
You can then retrieve the value corresponding to a given key with
vals["key42"]
[1] 42
IIRC R uses hashing for character-based indexing, so lookups should be fast regardless of the size of your vector.
If your values can be arbitrary objects, then you do need a list.
vals <- list(1:100, lm(speed ~ dist, data=cars), function(x) x^2)
names(vals) <- c("numbers", "model", "function")
sq <- vals[["function"]]
sq(5)
[1] 25
If your question is about constructing the list, I wouldn't be too worried. R internally is copy-on-write (objects are only copied if their contents are modified), so doing something like
vals <- list(1:1000000, 1:1000000, <other big objects>)
will not actually make extra copies of everything.
Edit: I just checked, and R will copy everything if you do lst <- list(....)
. Go figure. So if you're already close to the memory limit on your machine, this won't work. On the other hand, if you do names(lst) <- ....
, it won't make another copy of lst
. Go figure again.
Creating a named list from two vectors (names, values)
You can use setNames()
setNames(as.list(c(1, 2)), c("foo", "bar"))
(for a list) or
setNames(c(1, 2), c("foo", "bar"))
(for a vector)
R: Vector of keys and vector of values to list
We can perform the operation in a single line with base R
as.list(setNames(values, keys))
#$key1
#[1] 1
#$key2
#[1] 2
#$key3
#[1] 3
Invert a list of (key, values) pairs
We may use stack
with split
in base R
with(stack(key_values_list), split(as.character(ind), values))
If the order needs to be maintained
with(stack(key_values_list), split(as.character(ind),
factor(values, levels = unique(values))))
Or with rep/lengths/unlist
setNames(as.list(rep(names(key_values_list),
lengths(key_values_list))), unlist(key_values_list))
match names between vectors and assign corresponding values
a[intersect(names(b), names(a))] <- b[intersect(names(b), names(a))]
> a
1 2 3 4 5 6 7 8 9 10
"e" NA NA NA "u" "n" NA NA "g" "j"
How to correctly use lists?
Just to address the last part of your question, since that really points out the difference between a list
and vector
in R:
Why do these two expressions not return the same result?
x = list(1, 2, 3, 4); x2 = list(1:4)
A list can contain any other class as each element. So you can have a list where the first element is a character vector, the second is a data frame, etc. In this case, you have created two different lists. x
has four vectors, each of length 1. x2
has 1 vector of length 4:
> length(x[[1]])
[1] 1
> length(x2[[1]])
[1] 4
So these are completely different lists.
R lists are very much like a hash map data structure in that each index value can be associated with any object. Here's a simple example of a list that contains 3 different classes (including a function):
> complicated.list <- list("a"=1:4, "b"=1:3, "c"=matrix(1:4, nrow=2), "d"=search)
> lapply(complicated.list, class)
$a
[1] "integer"
$b
[1] "integer"
$c
[1] "matrix"
$d
[1] "function"
Given that the last element is the search function, I can call it like so:
> complicated.list[["d"]]()
[1] ".GlobalEnv" ...
As a final comment on this: it should be noted that a data.frame
is really a list (from the data.frame
documentation):
A data frame is a list of variables of the same number of rows with unique row names, given class ‘"data.frame"’
That's why columns in a data.frame
can have different data types, while columns in a matrix cannot. As an example, here I try to create a matrix with numbers and characters:
> a <- 1:4
> class(a)
[1] "integer"
> b <- c("a","b","c","d")
> d <- cbind(a, b)
> d
a b
[1,] "1" "a"
[2,] "2" "b"
[3,] "3" "c"
[4,] "4" "d"
> class(d[,1])
[1] "character"
Note how I cannot change the data type in the first column to numeric because the second column has characters:
> d[,1] <- as.numeric(d[,1])
> class(d[,1])
[1] "character"
How to add variable key/value pair to list object?
R lists can be thought of as hashes- vectors of objects that can be accessed by name. Using this approach you can add a new entry to the list like so:
key <- "width"
value <- 32
mylist <- list()
mylist[[ key ]] <- value
Here we use the string stored in the variable key to access a position in the list much like using the value stored in a loop variable i to access a vector through:
vector[ i ]
The result is:
myList
$width
[1] 32
R + combine a list of vectors into a single vector
A solution that is faster than the one proposed above:
vec<-unlist(lst)
vec[which(c(1,diff(vec)) != 0)]
Convert named list to vector with values only
Use unlist
with use.names = FALSE
argument.
unlist(myList, use.names=FALSE)
How do I make a list of data frames?
This isn't related to your question, but you want to use =
and not <-
within the function call. If you use <-
, you'll end up creating variables y1
and y2
in whatever environment you're working in:
d1 <- data.frame(y1 <- c(1, 2, 3), y2 <- c(4, 5, 6))
y1
# [1] 1 2 3
y2
# [1] 4 5 6
This won't have the seemingly desired effect of creating column names in the data frame:
d1
# y1....c.1..2..3. y2....c.4..5..6.
# 1 1 4
# 2 2 5
# 3 3 6
The =
operator, on the other hand, will associate your vectors with arguments to data.frame
.
As for your question, making a list of data frames is easy:
d1 <- data.frame(y1 = c(1, 2, 3), y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1), y2 = c(6, 5, 4))
my.list <- list(d1, d2)
You access the data frames just like you would access any other list element:
my.list[[1]]
# y1 y2
# 1 1 4
# 2 2 5
# 3 3 6
Related Topics
Adding Regression Line Equation and R2 on Separate Lines Graph
Generating a Heatmap That Depicts the Clusters in a Dataset Using Hierarchical Clustering in R
Xpath to Extract Text After Br Tags in R
Getting a Slot's Value of S4 Objects
Divide Each Data Frame Row by Vector in R
How to Speed Up R Packages Installation in Docker
Reading in Files with Two Rows for Header
How to Preprocess Features When Some of Them Are Factors
Dealing with Readlines() Function in R
Add Image (Png File) to Header of PDF File Created with R
How Do Add a Column in a Data Frame in R
Multiple Colors in a Facet Strip Background
Saving a List of Plots by Their Names()
Scoping and Functions in R 2.11.1:What's Going Wrong
How to Plot the Linear Regression in R