高效将可变长度向量列表转换为带列名稠密矩阵的方法
高效生成可变长度向量列表的稠密逻辑矩阵
问题背景
我有一个可变长度的字符向量列表,示例数据生成代码如下:
set.seed(1) dat <- lapply(1:10, \(x) sample(letters, size = sample(1:10,1), replace = T))
当前使用arules包的as(transactions(dat), "matrix")方法生成带列名的稠密逻辑矩阵,但该方法效率不足,需要更高效的实现方式,同时保留以所有小写字母为列名的格式。
高效实现方法
方法1:基础R原生函数实现
核心思路是将列表转成长格式数据,通过table统计元素出现情况,再转换为逻辑矩阵:
# 生成行索引与元素的配对数据 long_dat <- data.frame( row = rep(seq_along(dat), lengths(dat)), val = unlist(dat) ) # 定义完整列名(所有小写字母) all_letters <- letters # 构造频数表并转为逻辑矩阵 result_matrix <- table(long_dat$row, long_dat$val) > 0 # 补充缺失列并按字母顺序排序 result_matrix <- result_matrix[, match(all_letters, colnames(result_matrix))] colnames(result_matrix) <- all_letters
该方法依赖基础R函数,避免了第三方包的额外开销,中等规模数据下效率优于arules方法。
方法2:data.table+稀疏矩阵加速
针对大规模数据,data.table的快速分组结合稀疏矩阵转换,能进一步降低内存占用并提升速度:
library(data.table) # 转换为data.table格式,生成行索引 dt <- data.table( row = rep(seq_along(dat), lengths(dat)), val = unlist(dat) ) # 生成稀疏矩阵并转为稠密逻辑矩阵 sparse_mat <- xtabs(~ row + val, data = dt, sparse = TRUE) result_matrix <- as.matrix(sparse_mat) > 0 # 补充缺失列并按字母排序 all_letters <- letters missing_cols <- all_letters[!all_letters %in% colnames(result_matrix)] result_matrix <- cbind(result_matrix, matrix(FALSE, nrow = nrow(result_matrix), ncol = length(missing_cols))) colnames(result_matrix) <- c(colnames(sparse_mat), missing_cols) result_matrix <- result_matrix[, order(colnames(result_matrix))]
稀疏矩阵的中间转换能有效减少内存消耗,适合处理十万级以上的大样本数据。
方法3:tidyverse风格实现
如果习惯tidyverse语法,可通过向量化操作实现,代码简洁易读:
library(tidyverse) result_matrix <- dat %>% enframe(name = "row", value = "val") %>% unnest(val) %>% mutate(present = TRUE) %>% pivot_wider(names_from = val, values_from = present, values_fill = FALSE) %>% select(all_of(letters)) %>% as.matrix() # 补充行名对应原列表索引 rownames(result_matrix) <- seq_along(dat)
该方法在中小规模数据下效率与基础R方法相当,代码可读性更强,便于维护。
性能参考
- 小规模数据(<1000行):三种方法效率相近,tidyverse风格代码更易理解
- 中等规模数据(1000-10000行):基础R与data.table方法的效率显著高于
arules - 大规模数据(>10000行):data.table+稀疏矩阵的组合内存占用最低,速度最快
内容的提问来源于stack exchange,提问作者mr.T
相关产品推荐
相关产品推荐

