我写了一个循环来有条件地替换列表列表中的元素。虽然对R来说还是比较新的,但我确信我并没有尽可能有效地解决这个问题。以下循环对我的实际数据运行非常缓慢(一小时左右)。我在下面列出了一个最小的工作示例,它完全复制了我的数据结构。
A <- matrix(c(0, 1, 1, 2, 0, 0, 1, 0, 1, 2, 0, 0), nrow = 2, ncol = 6, byrow = TRUE)
B <- matrix(c(1, 1, 1, 2, 0, 1, 1, 0, 1, 2, 0, 0), nrow = 2, ncol = 6, byrow = TRUE)
C <- matrix(c(1, 0, 0, 1, 0, 1), nrow = 1, ncol = 6, byrow = TRUE)
D <- matrix(c(0, 0, 0, 1, 1, 1), nrow = 1, ncol = 6, byrow = TRUE)
mList <-list(list(A, B))
dList <- list(list(C, D))
如果mList2
的第n项的元素j等于{{1},则循环的目标是将0
的第n项的第j列中的所有单元格替换为dList
}。
0
这是使用mList
# [[1]]
# [[1]][[1]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 0 1 1 2 0 0
# [2,] 1 0 1 2 0 0
#
# [[1]][[2]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 1 1 1 2 0 1
# [2,] 1 0 1 2 0 0
dList
# [[1]]
# [[1]][[1]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 1 0 0 1 0 1
#
# [[1]][[2]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 0 0 0 1 1 1
函数集的另一个未实现收益的实例吗?有没有更好的方法来做这个不涉及使用四个指数?
apply
导致:
for(i in 1:length(dList)) {
for(j in 1:length(dList[[i]])) {
for(k in 1:length(dList[[i]][[j]])) {
for(m in 1:nrow(mList[[i]][[j]])) {
mList[[i]][[j]][m, k] <-
ifelse(
dList[[i]][[j]][k] == 1,
mList[[i]][[j]][m, k],
0
)
}
}
}
}
答案 0 :(得分:2)
我会使用嵌套的lapply
循环输入列表的嵌套结构,使用单个向量化操作重新计算mList
中的相关条目,而不是通过列和行循环:< / p>
lapply(seq_along(dList), function(i) {
lapply(seq_along(dList[[i]]), function(j) {
t(t(mList[[i]][[j]]) * as.vector(dList[[i]][[j]] != 0))
})
})
# [[1]]
# [[1]][[1]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 0 0 0 2 0 0
# [2,] 1 0 0 2 0 0
#
# [[1]][[2]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 0 0 0 2 0 1
# [2,] 0 0 0 2 0 0
这里是相同结构列表的基准,在mList
中有10 x 10000个矩阵。我已经对您提供的解决方案,@ thelatemail的解决方案以及我的解决方案进行了基准测试:
set.seed(144)
A <- matrix(sample(0:2, 100000, replace=TRUE), nrow=10)
B <- matrix(sample(0:2, 100000, replace=TRUE), nrow=10)
C <- matrix(sample(0:1, 10000, replace=TRUE), nrow=1)
D <- matrix(sample(0:1, 10000, replace=TRUE), nrow=1)
mList <-list(list(A, B))
dList <- list(list(C, D))
OP <- function(mList, dList) {
for(i in 1:length(dList)) {
for(j in 1:length(dList[[i]])) {
for(k in 1:ncol(dList[[i]][[j]])) {
for(m in 1:nrow(mList[[i]][[j]])) {
mList[[i]][[j]][m, k] <-
ifelse(
dList[[i]][[j]][k] == 1,
mList[[i]][[j]][m, k],
0
)
}
}
}
}
mList
}
josilber <- function(mList, dList) {
lapply(seq_along(dList), function(i) {
lapply(seq_along(dList[[i]]), function(j) {
t(t(mList[[i]][[j]]) * as.vector(dList[[i]][[j]] != 0))
})
})
}
thelatemail <- function(mList, dList) {
Map(
function(L,s) Map(function(sL,ss) {sL[,ss] <- 0; sL}, L, s),
mList,
lapply(dList, function(x) lapply(x, function(y) y==0) )
)
}
library(microbenchmark)
microbenchmark(OP(mList, dList), josilber(mList, dList), thelatemail(mList, dList), times=10)
# Unit: milliseconds
# expr min lq mean median uq max neval
# OP(mList, dList) 12252.468288 13318.745019 13478.116388 13486.732412 13840.106332 14259.053497 10
# josilber(mList, dList) 2.299442 2.401806 2.561809 2.480822 2.552620 3.511609 10
# thelatemail(mList, dList) 4.259594 4.438562 4.683855 4.612297 5.002605 5.122605 10
两种解决方案的运行速度都要快1000倍,这主要是因为它们没有紧密地循环通过矩阵,而是以矢量化的方式执行操作。