You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在tidyverse imap迭代中子集化列表,实现矩阵Inflow承接前序Outflow

问题解决:递推提取子列表内前序矩阵的Outflow列

核心问题分析

你的代码存在两个关键问题导致无法获取前序矩阵的Outflow列:

  • 内层imap中的matL是传入的原始字符向量(比如mat_One对应的c("Boy", "Cat")),不是已经生成的矩阵列表,所以matL[[index-1]]取到的是字符串而非之前计算出的矩阵。
  • 代码中未定义balVector,会直接触发报错,需要补充定义。

修正后的代码

使用purrr::accumulate替代内层imap,它能在迭代过程中传递前一个计算结果,完美实现递推逻辑:

library(tidyverse)

matList <- list(mat_One = c("Boy", "Cat"), mat_Two = c("Boy", "Bat"))
allocate <- list(mat_One = c(0.6, 0.5, 0.4), mat_Two = c(0.4, 0.5, 0.6))
flowVector <- c(6, 5, 600) 
rates <- list(mat_One = 0.10, mat_Two = 0.20)
# 补充定义balVector(示例用flowVector替代,可根据实际需求修改)
balVector <- flowVector

createBucketMap <- function() {
  imap(matList, \(mat_group, group_name) {
    # 用accumulate递推生成矩阵列表
    accumulate(mat_group, \(prev, current) {
      alc <- allocate[[group_name]]
      rate <- rates[[group_name]]
      
      Inflow <- if(is.null(prev)) {
        # 第一个元素,用初始flowVector计算
        flowVector * alc
      } else {
        # 后续元素,提取前一个矩阵的Outflow列
        prev[, "Outflow"]
      }
      Due <- balVector * alc * rate
      Outflow <- Inflow
      
      cbind(Inflow, Due, Outflow)
    }, .init = NULL) |> 
      # 移除.init的NULL,保留实际生成的矩阵
      discard(is.null) |> 
      set_names(mat_group)
  })
}

# 运行测试
createBucketMap()

关键修正点

  1. 递推逻辑实现:用accumulate替代内层imap,prev参数会自动传入上一次迭代生成的矩阵,直接通过prev[, "Outflow"]提取目标列(矩阵支持通过列名字符串索引)。
  2. 初始值处理:通过.init = NULL和discard(is.null)处理第一个元素的初始计算逻辑。
  3. 变量修复:补充了balVector的定义,避免运行时触发未定义变量报错。

内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 21:00:34