r语言 - 根据另一个向量中的数据块分配二进制向量



我有一个数据框:

dat <- data.frame(diffsecs=(c(189, 245, 13988, 2396, 29601, 263, 297, 292, 230, 257, 192, 
286, 236, 261, 286, 268, 294, 260, 286, 299, 514, 2287, 234, 
195, 250, 519, 560, 3314, 12340, 186, 184, 180, 180, 180, 180, 
180, 180, 180, 180, 180, 3072, 180, 180, 206, 180, 180, 180, 
360, 180, 180, 180, 180, 5220, 180, 437, 246, 218, 212, 472, 
2356, 2641, 363, 425, 757, 403, 181, 355, 192, 192, 784, 238, 
250, 261, 272, 2554, 29524, 4482, 6762, 1252, 269, 303, 294, 
286, 273, 289, 274, 216, 255, 180, 252, 322, 238, 583, 289, 317, 
308, 305, 308, 312, 330)))

它具有多个连续行等于 180 的实例块。我想分配一个二进制向量,当 diffsecs 的值等于 180 时等于 1,否则等于 0。但是,我只希望它在 5 个或更多连续 180 个实例的块中等于 1。因此,如果有 3 个连续值 180,则二进制向量将等于 0。

我尝试使用循环

total<- nrow(dat)
len<- 1:total
for(i in len){
temp<- dat[i:(i+5),] 
xdiff<- ifelse(mean(temp$diffsecs)>178 & mean(temp$diffsecs)<182 ,1,0)
temp2<- cbind(dat[i,],xdiff)
if(i==1) {dat2 <- temp2}
else {dat2<- rbind(dat2,temp2)}
}

但它不管理它,并分配比要求更短的块。

你可以利用伟大的rle函数,它是反比的:

RLE <- rle(dat$diffsecs)
RLE$values <- ifelse(RLE$values == 180 & RLE$lengths >= 5,1,0)
dat2 <- cbind(dat,binarycol=inverse.rle(RLE))

正如@Frank正确指出的那样,您可以将第二行缩短为:

RLE$values <- as.integer(RLE$values == 180 & RLE$lengths >= 5)

甚至:

RLE$values <- RLE$values == 180 & RLE$lengths >= 5

如果FALSE/TRUE的向量适合您而不是0/1

使用 data.table,您可以使用rleid

library(data.table)
setDT(dat)
dat[, v := 
(diffsecs==180)*(.N >= 5)
, by = rleid(diffsecs == 180)][]

最新更新