Replace list items (exclude global assignment)

I have a non-nested list (pretty straight forward). Some elements are NA, but can be replaced by other elements from the same list. I can achieve this with the global assignment operator <<- . However, I am trying to learn the best practice (since this seems to give me notes when compiling the package for CRAN). Questions:

  • Can I achieve this without a global mission?
  • If not, how can I use assign appropriately (my approach seems to create a bunch of copies of the same dataset and may occur in memory).

I tried to assign and it does not work. I also tried to use lapply without global assignment, but I can only get the last item, not a list of every item that was replaced.

Here's the problem:

 #Fake Data L1 <- lapply(1:3, function(i) rnorm(1)) L1[4:5] <- NA names(L1) <- letters[1:5] #items to replace and their replacements (names of elements to replace) nulls <- names(L1[sapply(L1, function(x) is.na(x))]) replaces <- c("b", "a") #doesn't work (returns only last element) lapply(seq_along(nulls), function(i) { L1[[nulls[i]]] <- L1[[replaces[i]]] return(L1) }) #works but considered bad practice by many lapply(seq_along(nulls), function(i) { L1[[nulls[i]]] <<- L1[[replaces[i]]] }) #does not work (I try L1[["d"]] and still get NA) lapply(seq_along(nulls), function(i) { assign(paste0("L1[[", nulls[i], "]]"), L1[[replaces[i]]], envir = .GlobalEnv) }) #also bad practice bu I tried lapply(seq_along(nulls), function(i) { assign(paste0("L1$", nulls[i]), L1[[replaces[i]]], envir = .GlobalEnv) }) #This works but it feels like we're making a ton of copies of the same data set lapply(seq_along(nulls), function(i) { L1[[nulls[i]]] <- L1[[replaces[i]]] assign("L1", L1, envir = .GlobalEnv) }) 

Ultimately, I would like to do this without a global assignment, but if not, then what is best for building a CRAN package.

+6
source share
2 answers

There is a replace function here that will do this for you:

 replace(L1, match(nulls, names(L1)), L1[match(replaces, names(L1))]) 

You can also use a slightly simpler which(is.na(L1)) instead of match(nulls, names(L1))

+10
source

For completeness, a for loop is suggested here, since some similar circumstances do not allow the use of replace :

 for(i in seq_along(a[!apps])){ L1[[nulls[i]]] <- L1[[replaces[i]]] } 
+4
source

All Articles