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

如何用apply系列函数向量化实现列表索引遍历与矩阵更新?

问题描述

我有一个嵌套列表:

xx = list("a_1" = list("A", "C"), 
          "a_2" = list("B", "C"), 
          "a_3" = list("B", "B"), 
          "a_4" = list("C", "B"), 
          "a_5" = list("B", "A"),
          "a_6" = list("B", "A"))

该列表包含重复子列表(如a_5和a_6)。我需要用它更新一个初始化为0的矩阵:

m = matrix(data = 0, nrow = 3, ncol = 3)         # 初始化零矩阵
rownames(m) = c("A", "B", "C")                   # 设置行名
colnames(m) = c("A", "B", "C")                   # 设置列名

需求是给每个子列表对应的矩阵索引位置的值加1。用for循环可轻松实现:

for (item in xx) {
  # 对应矩阵位置加1
  m[item[[1]], item[[2]]] = m[item[[1]], item[[2]]] + 1
}

得到预期输出:

A B C
A 0 0 1
B 2 1 1
C 0 1 0

但处理大型列表时该方法效率较低,我尝试嵌套使用lapply和sapply未成功,希望用apply系列函数实现向量化操作,请教具体方法?

解决方案

方法1:sapply转矩阵 + 频次统计

先将嵌套列表转换为两行的矩阵,每行对应子列表的第一个和第二个元素,再用table统计组合出现的次数,最后将统计结果映射到目标矩阵中:

# 将嵌套列表转为矩阵,每行对应子列表的两个元素
xx_mat <- sapply(xx, function(x) unlist(x))
# 统计每个(row, col)组合的出现次数
counts <- table(xx_mat[1, ], xx_mat[2, ])
# 将统计结果赋值给初始矩阵
m[rownames(counts), colnames(counts)] <- counts

这种方法完全向量化,处理大型数据集时效率远高于for循环,且代码简洁。

方法2:lapply提取索引 + 批量更新

如果偏好使用lapply,可以先提取所有索引对,合并为矩阵后批量更新矩阵值:

# 提取所有(row, col)索引对
indices <- lapply(xx, function(x) c(x[[1]], x[[2]]))
# 将索引对合并为矩阵
indices_mat <- do.call(rbind, indices)
# 批量对对应矩阵位置加1
m[indices_mat] <- m[indices_mat] + 1

利用矩阵的索引特性:当传入一个两列矩阵作为索引时,每一行对应一个(row, col)位置,可直接批量完成累加操作。

方法3:vapply高效提取索引

vapply比lapply更高效,因为可以预先指定返回值类型,适合处理大型列表:

# 用vapply提取索引,指定返回长度为2的字符向量
indices <- vapply(xx, function(x) unlist(x), character(2))
# 转置后得到每行是一个索引对的矩阵
indices_mat <- t(indices)
# 批量更新矩阵值
m[indices_mat] <- m[indices_mat] + 1

内容的提问来源于stack exchange,提问作者Matthew Cassell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:05:35