首页 > 解决方案 > R data.table 按列值设置子集

问题描述

我想知道data.table根据某些列值的出现选择行的最有效或最干净的方法是什么。例如,在一个 7 列数据表中,每个值为 1 或 0,我希望所有行恰好有 2 个 1 值和 5 个 0 值(1 表示“存在”和 0“不存在”)。

到目前为止,这就是我正在做的事情,假设如下data.table(更大,这只是其中的一个示例)

                                    name D2A1.var D2B3.var D3A1.var D4A3.var D5B3.var H2A3.var H4A4.var MA_ancestor.var
Chrom_1;10000034;G;A Chrom_1;10000034;G;A        1        1        1        1        1        1        1               1
Chrom_1;10000035;G;A Chrom_1;10000035;G;A        1        1        1        1        1        1        1               1
Chrom_1;10000042;C;A Chrom_1;10000042;C;A        1        1        1        1        1        1        1               1
Chrom_1;10000051;A;G Chrom_1;10000051;A;G        1        1        1        1        1        1        1               1
Chrom_1;10000070;G;A Chrom_1;10000070;G;A        1        1        1        1        1        1        1               1
Chrom_1;10000084;C;T Chrom_1;10000084;C;T        1        1        1        1        1        1        1               1
Chrom_6;9997224;AT;A               Chrom_6;9997224;AT;A        0        0        0        0        0        1        0               1
Chrom_6;9998654;GTGTGTGTT;G Chrom_6;9998654;GTGTGTGTT;G        0        0        0        0        0        0        0               1
Chrom_6;9999553;TTTC;T           Chrom_6;9999553;TTTC;T        0        0        0        0        0        0        0               1

如果我想要我有 7 1 的所有行,假设在 D2A1.var 和 D3A1.var 中只有 1 我正在执行以下操作

ALL = DT[DT$MA_ancestor.var == 1 & DT$D2A1.var == 1 &DT$D2B3.var == 1 & DT$D3A1.var == 1 & DT$D4A3.var == 1 &DT$D5B3.var == 1 & DT$H2A3.var == 1 & DT$H4A4.var == 1,]
TWO = DT[DT$MA_ancestor.var == 0 & DT$D2A1.var == 1 &DT$D2B3.var == 0 & DT$D3A1.var == 1 & DT$D4A3.var == 0 &DT$D5B3.var == 0 & DT$H2A3.var == 0 & DT$H4A4.var == 0,]
DFlist=list(TWO, ALL)
DFlong = rbindlist(DFlist, use.names = TRUE, idcol = FALSE)

这将返回预期的结果并且速度足够快。然而,当有多个条件时,需要大量的输入和大量的data.table创作。有没有更快、更干净、更紧凑的方法来实现这一目标?

标签: rdata.tablerowsdata-manipulationmultiple-conditions

解决方案


我们可以.SDcols通过指定感兴趣的列来使用 。循环遍历 Data.table ( .SD) 的子集,创建一个list逻辑vector并将其Reduce变为单个逻辑vector&

ALL <- DT[, Reduce(`&`, lapply(.SD, `==`, 1), .SDcols = nm1]
TWO <- DT[, Reduce(`&`, lapply(.SD, `==`, 0), .SDcols = nm1]

在哪里

nm1 <- names(DT)[-1] #or change the names accordingly

推荐阅读