如何处理两个列表中的 NA?
How to deal with NA in two lists?
我有两个列表,我想让它们在 NA
方面保持一致。 Put NA 每当两个列表之一中有 NA 时,列表结构中的任何其他内容都不会改变。
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)
我试过了,但没有成功bis[is.na(lis)]=NA
期望的输出:
> 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
这里有一个选项:
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)
但是,由于有大量 Map
和 lapply
调用,可能会有更快/更有效的方法。
对于 >2 个列表的情况,您可以使用以下方法(假设每个列表具有相同的长度):
# 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)
现在您的原始列表已在全局环境中修改。
示例数据:
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))
)
使用 Map
创建矩阵列表,其中 NA
个位置为 NA
:
naposmtx <- Map(function(mtx1, mtx2){
nasmtx <- mtx1 + mtx2 # because NA + non-NA = NA
nasmtx[!is.na(nasmtx)] <- 0
nasmtx
}, lis, bis)
然后:
lis <- Map(`+`, lis, naposmtx)
bis <- Map(`+`, bis, naposmtx)
我有两个列表,我想让它们在 NA
方面保持一致。 Put NA 每当两个列表之一中有 NA 时,列表结构中的任何其他内容都不会改变。
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)
我试过了,但没有成功bis[is.na(lis)]=NA
期望的输出:
> 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
这里有一个选项:
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)
但是,由于有大量 Map
和 lapply
调用,可能会有更快/更有效的方法。
对于 >2 个列表的情况,您可以使用以下方法(假设每个列表具有相同的长度):
# 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)
现在您的原始列表已在全局环境中修改。
示例数据:
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))
)
使用 Map
创建矩阵列表,其中 NA
个位置为 NA
:
naposmtx <- Map(function(mtx1, mtx2){
nasmtx <- mtx1 + mtx2 # because NA + non-NA = NA
nasmtx[!is.na(nasmtx)] <- 0
nasmtx
}, lis, bis)
然后:
lis <- Map(`+`, lis, naposmtx)
bis <- Map(`+`, bis, naposmtx)