R语言压缩交易数据导出无空值CSV 适配arules::read.transactions
问题描述
- 核心需求:为arules包的
read.transactions函数准备交易数据,需将50万+条商品行级记录按发票维度聚合,每张唯一发票对应单行,目标格式示例:
Invoice001,CustomerID,Country,StockCodeXYZ,StockCode123
Invoice002,CustomerID,Country,StockCodeAAA
- 原始数据格式:同一张发票对应多个商品时,每个商品单独占一行,发票基础信息重复展示,示例:
Invoice001,CustomerID,Country,StockCodeXYZ
Invoice001,CustomerID,Country,StockCode123
Invoice002,CustomerID,Country,StockCodeAAA
- 已尝试方案及存在的问题:
- 使用
pivot_wider()搭配unite()处理,生成超2.85亿个空值单元格,输出为列表格式,既无法写入CSV,也无法被arules读取 - 尝试
keep(~!is.null(.))、discard(is.null)、compact()等空值清理方法均无效 - 尝试直接调用arules内置
read.transactions()读取,多次调试参数均报错
- 使用
- 数据集为UCI提供的在线零售开源数据集,初始加载代码如下:
library(readxl) url <- "https://archive.ics.uci.edu/ml/machine-learning-databases/00352/Online%20Retail.xlsx" destfile <- "Online_20Retail.xlsx" curl::curl_download(url, destfile) Online_20Retail <- read_excel(destfile) trans <- read.transactions(????????????)
可行解决方案
方案1:直接读取长格式数据(性能最优,推荐)
arules原生支持单事务单物品一行的长格式输入,不需要提前聚合为单行格式,之前调用报错是未正确指定格式参数。
操作步骤:
- 先做基础数据清洗,过滤取消订单、空商品编码等无效记录
- 将清洗后的数据临时写入CSV,调用
read.transactions时指定长格式参数即可
完整代码:
library(arules) # 基础清洗:过滤空商品编码、取消订单(发票号开头为C的是取消记录) retail_clean <- Online_20Retail[ !is.na(Online_20Retail$StockCode) & !grepl("^C", Online_20Retail$InvoiceNo), ] # 临时写入长格式CSV,直接从数据框转大文件容易出现格式异常 write.csv(retail_clean, "tmp_retail_long.csv", row.names = FALSE, quote = FALSE) # 读取为transactions对象 trans <- read.transactions( file = "tmp_retail_long.csv", format = "single", # 核心参数:指定输入为单物品每行的长格式 sep = ",", header = TRUE, cols = c("InvoiceNo", "StockCode"), # 依次指定事务ID列、物品ID列 rm.duplicates = TRUE # 自动去除同一发票内重复的商品记录 )
如果需要绑定CustomerID、Country等交易元数据,追加以下代码即可:
# 提取每个发票对应的唯一元数据 invoice_meta <- unique(retail_clean[, c("InvoiceNo", "CustomerID", "Country")]) # 匹配元数据到transactions对象 transactionInfo(trans) <- invoice_meta[ match(trans@itemsetInfo$transactionID, invoice_meta$InvoiceNo), c("CustomerID", "Country") ]
该方案完全不需要做宽表转换,不会产生冗余空值,50万条记录在普通配置电脑上数秒即可处理完成,生成的transactions对象可直接用于后续关联规则挖掘。
方案2:聚合为单行格式后读取(适配自定义CSV输出需求)
如果需要生成每张发票对应单行的CSV文件,不要用pivot_wider做宽表转换——商品SKU量级大时会生成海量稀疏空值,直接用分组字符串聚合的方式处理,内存占用低、速度快,以data.table实现为例:
library(data.table) library(arules) # 转换为data.table格式提升处理速度 setDT(retail_clean) # 按发票分组,拼接同发票下的所有商品编码 retail_agg <- retail_clean[, .( CustomerID = first(CustomerID), Country = first(Country), StockCodes = paste(unique(StockCode), collapse = ",") ), by = InvoiceNo] # 写入符合目标格式的CSV fwrite(retail_agg, "retail_transactions_wide.csv", col.names = FALSE, sep = ",") # 读取为transactions对象,指定为购物篮宽格式 trans <- read.transactions( file = "retail_transactions_wide.csv", format = "basket", sep = ",", quote = "", info = c("InvoiceNo", "CustomerID", "Country") # 指定前三列为交易元数据 )
该方案生成的CSV完全匹配预期的单发票单行格式,不会产生冗余空值。
注:处理完成后可删除临时生成的CSV文件节省磁盘空间。
内容的提问来源于stack exchange,提问作者GarminGuy
相关产品推荐
相关产品推荐

