David Moore
David Moore

Reputation: 968

Replacing values within list elements

I have the following two lists:

list1 <- list(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1), c(1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0), c(0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1))
list2 <- list(c(9, 10, 11, 12, 13), c(5, 6, 7, 8, 9, 10, 11, 12, 13), c(1, 2, 3, 8, 9, 10, 11, 12, 13))

list2 represents positions in list1 that I would like to convert to 0. In other words, I would like the 9th, 10th, 11th, 12th, and 13th values in the first element of list1 to be 0; I would like the 5th through 13th values in the second element of list1 to be 0; etc. The resulting list should be the following:

list3 <- list(c(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0), c(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), c(0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0))

How can I do this? Thanks!

Upvotes: 0

Views: 43

Answers (3)

Matt Tyers
Matt Tyers

Reputation: 2215

Using a simple loop in base R,

for(i in 1:length(list1)) {
   list1[[i]][list2[[i]]] <- 0
}

> list1
[[1]]
 [1] 1 1 1 1 1 1 1 1 0 0 0 0 0

[[2]]
 [1] 1 1 1 1 0 0 0 0 0 0 0 0 0

[[3]]
 [1] 0 0 0 1 1 1 1 0 0 0 0 0 0

You could also do it with an mapply() like below, with the SIMPLIFY=F forcing the function to return in list form.

funfun <- function(x, y, recode=0) {
   x[y] <- recode
   return(x)
}

mapply(list1, list2, FUN=funfun, SIMPLIFY=F)
[[1]]
 [1] 1 1 1 1 1 1 1 1 0 0 0 0 0

[[2]]
 [1] 1 1 1 1 0 0 0 0 0 0 0 0 0

[[3]]
 [1] 0 0 0 1 1 1 1 0 0 0 0 0 0

Upvotes: 1

Dave2e
Dave2e

Reputation: 24079

Here is a quick and dirty method using a for loop:

for(i in 1:length(list1)){
  list1[[i]][list2[[i]]]<-0
}

I am sure someone can improve on this using a lapply or a function from purrr.

Upvotes: 2

Calum You
Calum You

Reputation: 15072

We can do this with purrr::map2 from the tidyverse:

list1 <- list(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1), c(1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0), c(0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1))
list2 <- list(c(9, 10, 11, 12, 13), c(5, 6, 7, 8, 9, 10, 11, 12, 13), c(1, 2, 3, 8, 9, 10, 11, 12, 13))

library(purrr)
map2(
  .x = list1,
  .y = list2,
  .f = function(list, indexes){
    list[indexes] <- 0
    list
  }
)
#> [[1]]
#>  [1] 1 1 1 1 1 1 1 1 0 0 0 0 0
#> 
#> [[2]]
#>  [1] 1 1 1 1 0 0 0 0 0 0 0 0 0
#> 
#> [[3]]
#>  [1] 0 0 0 1 1 1 1 0 0 0 0 0 0

Created on 2018-10-22 by the reprex package (v0.2.0).

Upvotes: 2

Related Questions