R语言批量处理out列表元素的代码优化与错误修复求助
批量处理out$1和out$2的position以计算s和cost值的问题
前置R代码
首先是你提供的生成out对象的前置代码:
Nh<-matrix(c(17,26,30,17,23, 17 ,24, 23), nrow=2, ncol=4); Nh Sh<-matrix(c(8.290133, 6.241174, 6.096808, 7.4449672, 6.894924, 7.692115, 4.540521, 7.409122), nrow=2, ncol=4); Sh NhSh<-as.matrix(Nh*Sh); NhSh rh<-c( 0.70710678, 0.40824829, 0.28867513, 0.22360680, 0.18257419, 0.15430335, 0.13363062, 0.11785113, 0.10540926, 0.09534626); rh pv <- c() for (j in 1:2) { for (i in 1:4) { pv <- rbind(pv, NhSh[j,i]*rh) } } pv row.names(pv) <- rep(c(1:2), each = 4) lst<-lapply(split(seq_len(nrow(pv)), as.numeric(row.names(pv))), function(i) pv[i,]) data<-40 nlargest <- function(x, data) { res <- order(x)[seq_len(data)]; pos <- arrayInd(res, dim(x), useNames = TRUE); list(values = pv[res], position = pos) } out <- lapply(lst, nlargest, data = 40)
需求说明
你需要对out$1和out$2中的position批量执行以下步骤,得到对应的s和cost值(单例示例代码如下):
s1<-c(1,1,1,1); ch<-c(5,7,10,5); C<-150; a<-out$'1'$position for (j in a[40:1, "row"] ) { s1[j] <- s1[j]+1; cost1 <- sum(ch*s1); if (cost1>=C) break } s1; cost1 # Output # [1] 5 6 6 5 # [1] 152
尝试的代码及报错
你尝试了两段代码,但都出现了错误:
第一段代码及报错
mat = replicate (2,{x = matrix(data = rep(NA, 80), ncol = 2)}); mat for (k in 1:2) { mat[,,k]<-out$'k'$position } mat
报错信息:
Error in mat[, , k] <- out$k$position : number of items to replace is not a multiple of replacement length
第二段代码及报错
for (k in 1:2) { for (j in mat[,,k][40:1] ) { s[j] <- s[j]+1 cost <- sum(ch*s) if (cost>=C) break } } s; cost
报错信息:
Error : Error in s[j] <- s[j] + 1 : NAs are not allowed in subscripted assignments
解决方案
我们来逐个解决问题,实现批量处理:
问题分析
第一段代码的错误:
- 不能用
out$'k'来引用变量k对应的列表元素,应该用out[[k]](因为k是变量,列表的索引访问要用双括号); mat的维度定义有问题,out[[k]]$position是40行2列的矩阵,不需要提前创建80元素的矩阵,直接提取即可。
- 不能用
第二段代码的错误:
- 没有初始化
s变量,而且每次循环需要重新初始化s为c(1,1,1,1); - 遍历
mat[,,k][40:1]的方式不对,应该提取position中的row列值来遍历。
- 没有初始化
正确的批量处理代码
# 定义固定参数 ch <- c(5,7,10,5) C <- 150 # 初始化结果存储列表 results <- list() # 批量处理out中的两个元素 for (k in 1:2) { # 获取当前组的position矩阵 pos_matrix <- out[[k]]$position # 初始化s s <- c(1,1,1,1) cost <- 0 # 从第40行倒序遍历row列的值 for (j in pos_matrix[40:1, "row"]) { s[j] <- s[j] + 1 cost <- sum(ch * s) # 达到成本阈值就退出循环 if (cost >= C) break } # 存储当前组的结果 results[[paste0("group_", k)]] <- list(s = s, cost = cost) } # 查看结果 results$group_1 results$group_2
这段代码的逻辑:
- 用
out[[k]]正确访问列表的第k个元素; - 每次循环都重新初始化
s,避免之前的循环结果干扰; - 直接遍历
pos_matrix中的row列值,确保索引正确; - 把每个组的
s和cost存储到results列表中,方便后续查看。
运行这段代码后,你就能得到和单例示例一致的group_1结果,以及group_2对应的s和cost值了。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

