How to deal with NA in two lists?

I have two lists, and I want to make them consistent in terms of NA . Put NA Whenever there is an NA in one of the two lists, without changing anything in the structure of the list.

 set.seed(123) m1 <- matrix(nrow=2,ncol=2,data=runif(4)) m1[1,1] <- NA m2 <- matrix(nrow=2,ncol=2,data=runif(4)) m2[1,2] <- NA lis <- list(m1, m2) m1 <- matrix(nrow=2,ncol=2,data=runif(4)) m2 <- matrix(nrow=2,ncol=2,data=runif(4)) m2[2,1] <- NA bis <- list(m1, m2) 

I tried this, but without success bis[is.na(lis)]=NA

Required Conclusion:

  > lis [[1]] [,1] [,2] [1,] NA 0.9568333 [2,] 0.4566147 0.4533342 [[2]] [,1] [,2] [1,] 0.9404673 NA [2,] 0.0455565 NA > bis [[1]] [,1] [,2] [1,] NA 0.9568333 [2,] 0.4566147 0.4533342 [[2]] [,1] [,2] [1,] 0.6775706 NA [2,] 0.5726334 NA 
+5
source share
2 answers

There is an option here:

 z <- Map("|", lapply(lis, is.na), lapply(bis, is.na)) bis <- Map(function(mat, idx) {mat[idx] <- NA; mat}, bis, z) lis <- Map(function(mat, idx) {mat[idx] <- NA; mat}, lis, z) 

However, there may be faster / more efficient approaches due to the numerous calls to Map and lapply .


In the case of s> 2 lists, you can use the following approach (provided that each list has the same length):

 # create a named list - naming is important if you want to # assign them back to the global environment later on mylist <- list(lis = lis, bis = bis, kis = kis) n <- max(lengths(mylist)) z <- lapply(1:n, function(i) { Reduce(`+`, Map(function(y) is.na(y[[i]]), mylist))>0 }) mylist <- lapply(mylist, function(mat) { Map(function(m, idx) {m[idx] <- NA; m}, mat, z) }) # to assign them back to the global environment, run: list2env(mylist, envir = .GlobalEnv) 

Now the source lists are changed in the global environment.

Sample data:

 set.seed(123) n <- 4 lis <- list( m1 = matrix(nrow=n,ncol=n,data=sample(c(NA, 1:10), n*n, TRUE)), m2 = matrix(nrow=n,ncol=n,data=sample(c(NA, 1:10), n*n, TRUE)) ) bis <- list( m1 = matrix(nrow=n,ncol=n,data=sample(c(NA, 1:10), n*n, TRUE)), m2 = matrix(nrow=n,ncol=n,data=sample(c(NA, 1:10), n*n, TRUE)) ) kis <- list( m1 = matrix(nrow=n,ncol=n,data=sample(c(NA, 1:10), n*n, TRUE)), m2 = matrix(nrow=n,ncol=n,data=sample(c(NA, 1:10), n*n, TRUE)) ) 
+3
source

Using Map to create a list of matrices with positions NA as NA :

 naposmtx <- Map(function(mtx1, mtx2){ nasmtx <- mtx1 + mtx2 # because NA + non-NA = NA nasmtx[!is.na(nasmtx)] <- 0 nasmtx }, lis, bis) 

Then:

 lis <- Map(`+`, lis, naposmtx) bis <- Map(`+`, bis, naposmtx) 
+4
source

Source: https://habr.com/ru/post/1241108/


All Articles