使用data.table

时间:2015-10-29 13:49:56

标签: r indexing data.table sequence chunks

假设我有一个数据集,其中长度为1的序列是非法的,长度2是合法的,大于长度5是非法的但是允许将更长的序列分解为< = 5序列。

set.seed(1)
DT1 <- data.table(smp = 1, R=sample(0:1, 20000, rep=TRUE), Seq = 0L)
DT1[, smp:=1:length(smp)]
DT1[, Seq:=seq(.N), by=list(cumsum(c(0, abs(diff(R)))))]

这最后一行直接来自: Creating a sequence in a data.table depending on a column

DT1[, fix_min:=ifelse((R==TRUE & Seq==1) | (R==FALSE), FALSE, TRUE)]
fixmin_idx2 <- which(DT1[, fix_min==TRUE])
DT1[fixmin_idx2 -1, fix_min:=TRUE]

现在我的长度为2的法官已正确标记。分解&gt; 5s。

DT1[R==1 & Seq==6, fix_min:=FALSE]
DT1[,Seq2:=seq(.N), by=list(cumsum(c(0, abs(diff(fix_min)))))]
DT1[R==1 & Seq2==6, fix_min:=FALSE]
fixSeq2_idx7 <- which(DT1[,fix_min==TRUE] & DT1[,Seq2==7])
fixSeq2_idx7
[1] 10203 13228
DT1[fixSeq2_idx7,]
 smp R Seq fix_min Seq2
1: 10203 1  13    TRUE    7
2: 13228 1  13    TRUE    7
DT1[fixSeq2_idx7 + 1,]
 smp R Seq fix_min Seq2
1: 10204 1  14    TRUE    8
2: 13229 0   1   FALSE    1

现在测试Seq2 == 7后面是Seq2 == 8,这将是合法的2长度。我一个7然后是一个8而一个没有跟着一个8.然后我就被卡住了。我尝试过的所有内容都将fix_min设置为TRUE或更改为TRUE和FALSE。

非常感谢任何指导。

1 个答案:

答案 0 :(得分:2)

如果我正确理解您的问题,您希望在fix_minFALSE时将R == 0设置为R == 1 & (1 =< Seq < 6 | Seq > 6)。然后以下应该给你你想要的东西:

# recreating the data from your first code block
set.seed(1)
DT1 <- data.table(R=sample(0:1, 20000, rep=TRUE))[, smp:=.I
                                                  ][, Seq:=seq(.N), by=rleid(R)
                                                    ][, Seq2 := Seq[.N], by=rleid(R)]

# adding the needed 'fix_min' column
DT1[, fix_min := (R==1 & Seq[.N] > 1 & Seq%%6!=0), by=rleid(R)
    ][R==1 & Seq%%6==1 & Seq2%%6==1 & Seq==Seq2, fix_min := FALSE]

解释

  • data.table(R=sample(0:1, 20000, rep=TRUE))创建 data.table
  • 的基础
  • [, smp:=.I]创建索引并将其添加到 data.table
  • by=rleid(R)识别序列;看看它的作用:data.table(R=sample(0:1, 20000, rep=TRUE))[, seq.id:=rleid(R)]
  • [, Seq:=seq(.N), by=rleid(R)]为每个序列创建一个索引,并将其添加到 data.table ;序列由rleid(R)
  • 标识
  • [, Seq2 := Seq[.N], by=rleid(R)]创建一个变量,其中包含一个指示序列长度的值
  • fix_min := (R==1 & Seq[.N] > 1 & Seq%%6!=0)创建一个TRUE值的逻辑向量,其中R==1&amp;序列的长度大于一(Seq[.N] > 1),不包括序列号是6Seq%%6!=0)的倍数的值
  • R==1 & Seq%%6==1 & Seq2%%6==1 & Seq==Seq2过滤 data.table ,如下所示:仅R==1&amp;序列值为71319等(Seq%%6==1)&amp;序列的长度为71319等,仅从符合其他条件的序列中选择最后一行(Seq==Seq2)。使用fix_min := FALSE,您可以将其设置为FALSE