【问题标题】:How to efficiently identify sequential changes across multiple columns in a data table?如何有效地识别数据表中多个列的顺序变化?
【发布时间】:2021-02-10 01:44:49
【问题描述】:

我有一个非常大的数据表,其中包含以下列。其中 pos1 和 pos2 给出了不同类别 cat1 和 cat2 的对齐序列。

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

x <- 1:60
y <- 100:41

dt <- data.table(cat1 = c(rep("A", 40), rep("B", 60)),
                 cat2 = c(rep("A", 75), rep("C", 25)),
                 pos1 = c(x[-sample(x, 10)], x[-sample(x, 10)]),
                 pos2 = c(x[-sample(x, 10)], y[-sample(x, 10)])

我需要创建一个分组列,其中当 cat1 或 cat2 之一发生更改,或者 pos1 或 pos2 之间的差异大于 1 时,id 会更改。

我试过如下:

dt$grp <- as.numeric(paste0(rleid(c(0,cumsum(as.numeric(with(dt, cat1[1:(length(cat1)-1)] != cat1[2:length(cat1)]))))),
                                  rleid(c(0,cumsum(as.numeric(with(dt, cat2[1:(length(cat2)-1)] != cat2[2:length(cat2)]))))),
                                  rleid(c(0, cumsum(abs(diff(dt$pos1)) > 1))),
                                  rleid(c(0, cumsum(abs(diff(dt$pos2)) > 1))) ))

但是,这种方法很慢,并且会在我的数据集中产生一些错误。有人对如何改进有任何建议吗?

任何帮助将不胜感激!

【问题讨论】:

    标签: r data.table grouping sequence


    【解决方案1】:

    由于您使用的是 data.table 包,我会执行以下操作。

    dt[,`:=`(pos1id=rleid(cumsum(abs(diff(c(0,pos1)))>1)),
             pos2id=rleid(cumsum(abs(diff(c(0,pos2)))>1)),
             cat1id=rleid(cat1),
             cat2id=rleid(cat2))][
       , `:=`(grp=.GRP), by = c("pos1id","pos2id",
                                "cat1id","cat2id")         
             ]
    

    := 操作符在原地修改数据,这通常很快。此外,您不需要一次性完成所有这些操作,您可以创建多个列,然后根据 data.table 的内部.GRP 参数对它们进行索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-09
      • 1970-01-01
      • 2015-05-28
      • 1970-01-01
      相关资源
      最近更新 更多