【问题标题】:Create all cross combinations, respecting the column hierarchy创建所有交叉组合,尊重列层次结构
【发布时间】:2021-09-02 16:56:21
【问题描述】:

从我的data.tableDT.in,我想创建所有交叉连接组合,但不仅仅是CJ(_all_my_var_)

我需要执行这样的操作:

CJ(var1)
CJ(var1, var2)
CJ(var1, var2, var3)
...

这是我的代表:

library(data.table)
set.seed(999)

DT.in <- data.table(lvl1 = rep('AA', 200),
                 code = sample(c('D44', 'J21'), 200, replace = TRUE),
                 var = sample(c('Z3R', 'TR5', 'JKL', 'FR5', 'TFX'), 200, replace = TRUE),
                 test = sample(c('ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN'), 200, replace = TRUE))

foo.1 <- DT.in[, .(new = CJ(lvl1, unique = TRUE))]
foo.2 <- DT.in[, .(new = CJ(lvl1, code, unique = TRUE))]
foo.3 <- DT.in[, .(new = CJ(lvl1, code, var, unique = TRUE))]
foo.4 <- DT.in[, .(new = CJ(lvl1, code, var, test, unique = TRUE))]

DT.out <- rbindlist(list(foo.1, foo.2, foo.3, foo.4), fill = TRUE)

我的 DT.out 是我想要的,但当然,我需要自动执行此操作,变量的名称和数量永远不会相同。而我还是做不到……

我们将不胜感激。

(也许从 DT.in 到 DT.out 有另一种方式...?)

【问题讨论】:

    标签: r data.table cross-join


    【解决方案1】:

    我们可以使用do.callCJ

    1. 使用lapply 循环遍历“DT.in”的列序列
    2. 获取sequence,以根据数字索引选择列
    3. do.call 中应用CJ
    4. list 中的输出数据集与rbindlist 绑定到单个数据集
    library(data.table)
    DT.out2 <- rbindlist(lapply(seq_along(DT.in), function(i) 
          do.call(CJ, c(DT.in[, seq(i), with = FALSE], unique = TRUE))), fill = TRUE)
    setnames(DT.out2, paste0("new.", names(DT.out2)))
    

    -检查 OP 的输出

    identical(DT.out, DT.out2)
    [1] TRUE
    

    【讨论】:

    • 呜呼如此令人印象深刻,多么快速的回答!并感谢您提供详细信息。
    猜你喜欢
    • 1970-01-01
    • 2013-06-07
    • 2018-10-18
    • 1970-01-01
    • 2019-03-20
    • 2014-03-01
    • 2021-04-26
    • 2017-04-18
    • 1970-01-01
    相关资源
    最近更新 更多