Rich Scriven
Rich Scriven

Reputation: 99331

Inserting values in one list into another list by index

I have two lists x and y, and a vector of indices where.

x <- list(a = 1:4, b = letters[1:6])
y <- list(a = c(20, 50), b = c("abc", "xyz"))
where <- c(2, 4)

I want to insert y into x at the indices in where, so that the result is

list(a = c(1,20,2,50,3,4), b = c("a", "abc", "b", "xyz", "c", "d", "e", "f"))
#$a
#[1]  1 20  2 50  3  4
#
#$b
#[1] "a"   "abc" "b"   "xyz" "c"   "d"   "e"   "f"  

I've been trying it with append, but it's not working.

lapply(seq(x), function(i) append(x[[i]], y[[i]], after = where[i]))
#[[1]]
#[1]  1  2 20 50  3  4
#
#[[2]]
#[1] "a"   "b"   "c"   "d"   "abc" "xyz" "e"   "f"  

This is appending at the wrong index. Plus, I want to retain the list names in the process. I also don't know if append is the right function for this, since I've literally never seen it used anywhere.

What's the best way to insert values from one list into another list using an index vector?

Upvotes: 2

Views: 179

Answers (2)

MrFlick
MrFlick

Reputation: 206243

How about an mapply solution

x <- list(a = 1:4, b = letters[1:6])
y <- list(a = c(20, 50), b = c("abc", "xyz"))
where <- c(2, 4)

mapply(function(x,y,w) {
    r <- vector(class(x), length(x)+length(y))
    r[-w] <- x
    r[w] <- y
    r
}, x, y, MoreArgs=list(where), SIMPLIFY=FALSE)

which returns

$a
[1]  1 20  2 50  3  4

$b
[1] "a"   "abc" "b"   "xyz" "c"   "d"   "e"   "f"  

which seems to be the results you desire.

Upvotes: 1

flodel
flodel

Reputation: 89057

Here I created a APPEND function that is an iterative (via Reduce) version of append:

APPEND <- function(x, where, y)
   Reduce(function(z, args)do.call(append, c(list(z), args)),
          Map(list, y, where - 1), init = x)

Then you just need to call that function via Map:

Map(APPEND, x, list(where), y)

Upvotes: 1

Related Questions