R中数据集的multinomial expansion自动化实现及内存问题解决
自动生成数据集列的任意阶多项式展开列及poly函数内存问题解决
一、实现自动化多项式展开函数
针对需求:给定任意N列T行的数据集,生成所有d阶多项式展开的隐含列(不考虑系数),我们可以实现一个仅接收ds(数据集)和d(阶数)作为参数的函数:
函数代码
multinomial_expand <- function(ds, d) { n_cols <- ncol(ds) col_names <- colnames(ds) # 生成所有满足sum(exponents) = d的非负整数指数组合 exponents <- do.call(expand.grid, rep(list(0:d), n_cols)) exponents <- exponents[rowSums(exponents) == d, ] # 生成每一项的列名 term_names <- apply(exponents, 1, function(exp) { parts <- mapply(function(name, e) { if (e == 0) NULL else if (e == 1) name else paste0(name, "^", e) }, col_names, exp) paste(parts[!sapply(parts, is.null)], collapse = "*") }) # 计算每一项的值 result <- apply(exponents, 1, function(exp) { apply(ds, 1, function(row) prod(row^exp)) }) colnames(result) <- term_names return(result) }
测试示例
用题目中的示例数据测试:
set.seed(123) ds <- cbind("a"=rnorm(10),"b"=rnorm(10),"c"=rnorm(10)) # 生成2阶多项式展开列 expanded_ds <- multinomial_expand(ds, 2) head(expanded_ds)
输出会包含a^2、b^2、c^2、a*b、a*c、b*c共6列,和手动实现的结果一致。
二、poly函数内存错误的解释及解决方案
错误原因
你遇到的Error: cannot allocate vector of size 9469.2 Gb,本质是poly函数的用法错误:大概率是你将数据集的行当作变量传入(比如转置了数据集),此时变量数等于行数T。当T较大时,d=2的多项式项数是组合数C(T+1, 2),这个数值会随T呈平方级爆炸式增长,所需内存远超系统承载能力。比如当T≈48万时,C(T+1,2)≈1.15e11,仅存储这些double类型的元素就需要约9400Gb内存,正好匹配错误提示的数值。
解决方案
- 正确使用poly函数:确保将数据集的每一列作为变量传入,同时设置
raw=TRUE生成原始多项式项(而非默认的正交多项式):
# 正确用法:生成2阶原始多项式展开列 poly_result <- poly(ds, degree=2, raw=TRUE)
对于N=26、d=2的场景,仅会生成C(26+2-1,2)=351项,完全不会有内存压力。
- 使用自定义函数:直接使用前面实现的
multinomial_expand函数,逻辑更直观,还能灵活控制列名格式,避免poly函数的用法陷阱。
内容的提问来源于stack exchange,提问作者oibaFox
相关产品推荐
相关产品推荐

