R-搜索数字序列

时间:2019-03-13 09:13:10

标签: r dataframe sequence

我有一个看起来像这样的数据框:

   nr  grp start stop l1 ratio
   11   1   300  350  +   1.0                  
   12   1   400  450  -   0.8                  
   13   1    50  550  +   1.0                  
   14   1   600  650  -   1.0                  
   21   1   800  850  -   1.0                  
   36   1  1000 1050  +   0.0       
   37   1  1100 1200  +   0.9
   38   1  1250 1300  -   0.7
   39   1  1350 1400  +   1.0

,我必须找到连续数字的序列并将其移至新的df。 我需要拉出序列的整个第一行,并仅替换从序列的最后一行获取的停止列的值。

最终的df应该如下所示:

  nr  grp start stop l1 ratio
  11   1   300  650   +   1.0                  
  36   1   1000 1400  -   0.8 

我试图这样做:

t1<- read.table('aa.txt',sep = "\t", header=TRUE)
head(t1)
t1$chk <- NA
dl <- length(t1$nr)
for (i in 1:dl){
  if(isTRUE(t1$nr[i]+1 == t1$nr[i+1])){
  t1$chk[i] <- "t"  
  }else{
    t1$chk[i] <- 'F'
    }
}

我收到这个消息:

   nr  grp start stop l1 ratio chk
   11   1   300  350  +   1.0   t             
   12   1   400  450  -   0.8   t              
   13   1    50  550  +   1.0   t              
   14   1   600  650  -   1.0   F              
   21   1   800  850  -   1.0   F              
   36   1  1000 1050  +   0.0   t   
   37   1  1100 1200  +   0.9   t
   38   1  1250 1300  -   0.7   t
   39   1  1350 1400  +   1.0   F

之后,我想将chk列中所有带有“ t”的行移至新的df。不幸的是,我有一个问题,因为其中不包括最后的序列数。有人知道如何解决吗?

2 个答案:

答案 0 :(得分:2)

我们可以使用diff为序列中的每个更改创建组,如果组中的行多于1,则从每个组中仅选择第一行,并将stop的值更新为其中的最后一个值小组。

library(dplyr)

df %>%
   group_by(group = cumsum(c(1, diff(nr) != 1))) %>%
   mutate(stop = last(stop)) %>%
   filter(n() > 1 & row_number() == 1) %>%
   ungroup() %>%
   select(-group)

#     nr   grp start  stop l1    ratio
#  <int> <int> <int> <int> <fct> <dbl>
#1    11     1   300   650 +         1
#2    36     1  1000  1400 +         0

答案 1 :(得分:1)

易于使用data.table:

DT <- fread("   nr  grp start stop l1 ratio
            11   1   300  350  +   1.0                  
            12   1   400  450  -   0.8                  
            13   1    50  550  +   1.0                  
            14   1   600  650  -   1.0                  
            21   1   800  850  -   1.0                  
            36   1  1000 1050  +   0.0       
            37   1  1100 1200  +   0.9
            38   1  1250 1300  -   0.7
            39   1  1350 1400  +   1.0")

setDT(DT) #if you haven't imported with fread

#create group ID, here for didactic reason
DT[, groups := cumsum(c(TRUE, diff(nr) != 1))]

#take first row and replace stop from last row
DT[, if (.N > 1) {
  res <- .SD[1]
  res$stop <- .SD[.N, stop]
  res
  } else NULL, by = groups]
#   groups nr grp start stop l1 ratio
#1:      1 11   1   300  650  +     1
#2:      3 36   1  1000 1400  +     0