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

分组DT调用combn报错‘n < m’及修正时遇新问题

解决data.table中combn报错及do.call参数错误的问题

首先,咱们拆解下你遇到的两个问题,再给出针对性的解决方案:

问题1:combn(Materials, 2, simplify = FALSE) : n < m

这个错误的原因很明确:你的数据里存在部分Order.number对应的Materials只有1条记录(甚至为空),而combn(x,2)要求输入的向量长度至少为2,没法选出2个元素的组合时自然会报错。

问题2:Error in do.call(rbind, function(x) ...) : second argument must be a list

你尝试用函数判断材料长度,但do.call的第二个参数必须是可被rbind处理的列表/数据框,直接传入函数对象不符合参数要求,所以触发了这个错误。


正确的解决方案

我们可以在data.table的分组操作里,先判断当前订单的材料数量,只有数量≥2时才生成组合,否则返回空值跳过该组,同时优化组合生成逻辑:

library(data.table)

# 初始化并排序data.table(你已完成的步骤)
DT <- data.table(Order.number = X$Order.number, Materials = X$Materials)
setorder(DT, Order.number, Materials)

# 核心处理代码
ans <- DT[, {
  # 可选:对当前订单的材料去重,避免同一订单内重复材料生成无效组合
  unique_mats <- unique(Materials)
  # 判断材料数量是否满足生成两两组合的要求
  if (length(unique_mats) >= 2) {
    # 生成两两组合并转置为数据框(t()让组合直接变成两列)
    as.data.table(t(combn(unique_mats, 2)))
  } else {
    # 材料数量不足时返回NULL,该组不会被计入结果
    NULL
  }
}, by = Order.number][, .N, by = .(V1, V2)]

代码说明

  1. 分组内判断材料数量:通过length(unique_mats) >=2筛选出能生成组合的订单,跳过材料数量不足的组,从根源避免combn的报错。
  2. t(combn(...))的作用:默认combn返回按列排列的组合,转置后直接得到两列的V1和V2,不需要再用do.call(rbind,...)处理嵌套列表,简化了逻辑。
  3. 去重操作:如果你的数据里存在同一订单重复记录相同材料的情况,unique(Materials)可以避免生成(A,A)这类无效组合;如果不需要去重,直接去掉unique()即可。

内容的提问来源于stack exchange,提问作者M.A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:53:03