Make List of Vectors by Joining Pair-Corresponding Elements of 2 Vectors Efficiently in R

Make list of vectors by joining pair-corresponding elements of 2 vectors efficiently in R

mapply(c, v1, v2, SIMPLIFY = FALSE)
#$a
#[1] "a" "1"

#$b
#[1] "b" "2"

#$c
#[1] "c" "3"

#$d
#[1] "d" "4"

#$e
#[1] "e" "5"

(OR more precisely with respect to your OP which returns an unnamed list use mapply(c, v1, v2, SIMPLIFY = FALSE, USE.NAMES = FALSE) ).

How to make a list of pairs from 2 vectors

You are almost there:

mapply(c, X0, X1, SIMPLIFY = FALSE)
# [[1]]
# [1] -Inf 1
#
# [[2]]
# [1] 1 2
# ...
# [[11]]
# [1] 10 Inf

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.

Pasting two vectors with combinations of all vectors' elements

You can use this, but there may be a simpler solution :

R> apply(expand.grid(vars, vis), 1, paste, collapse=".")
[1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"

expand.grid gives back a data.frame which when used with apply, apply will convert it to a matrix. This is just unnecessary (and inefficient on large data). outer gives a matrix and also takes function argument. It'll be much efficient on huge data as well.

Using outer:

as.vector(outer(vars, vis, paste, sep="."))
# [1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"

corresponding comparison of vectors within a list in R

If we need an elementwise comparison, use Reduce

out1 <- Reduce(`|`, mylist)

which is similar to the do.call method with Map and any

out2 <- unlist(do.call(Map, c(f = any, mylist)))
all.equal(out1, out2)
#[1] TRUE

In the nested for loop

mylist[[j]][[i]]

is a single element in the list which is getting wrapped with any. Therefore, the my_vector which was initialized as the length of the first vector element of 'mylist' is getting recycled and it will return the output of the last list element

If we make a small change in the function for loop, it would give the same output i.e. the key is to check whether the elements in 'my_vector' at the same position along with the element indexed from 'mylist' have any TRUE values instead of just checking a single element and overwriting it to my_vector

 my_function<-function(){
my_vector <- logical(length(mylist[[1]]))
for (i in 1:length(mylist[[1]])){
for (j in 1:length(mylist)){
my_vector[i] <- any(c(my_vector[i], mylist[[j]][[i]]))
}
}
my_vector
}

out3 <- my_function()
identical(out1, out3)
#[1] TRUE

Apply a function to two vectors the R way?

x <- c(1,2,3,NA,5)
y <- c(6,7,8,9,10)

x[is.na(x)] <- y[is.na(x)]

See the above. using is.na() on x returns a logical vector where it is TRUE for the NA elements of x. Using these in the selector for X and Y will select only those NA elements. Using it in assignment will replace the NA elements from x with the corresponding ones from Y.

That will be much faster than looping as the vector gets large.

Create a list of named lists from three vectors in R

I think you are looking for Map

l <- Map(list, id1, id2) # thanks to @thelatemail for suggested improvement
names(l) <- names
identical(mylist, l)
# TRUE

Merge Two Lists in R

If lists always have the same structure, as in the example, then a simpler solution is

mapply(c, first, second, SIMPLIFY=FALSE)

Difference of two character vectors with substring

We can paste the 'a' elements to a single string with | as the delimiter, use that as pattern in grepl, negate (!) to subset 'b'.

 b[!grepl(paste(a, collapse="|"), b)]


Related Topics



Leave a reply



Submit