【问题标题】:Conditional statement for groups of rows of an R dataframeR数据帧的行组的条件语句
【发布时间】:2020-05-26 02:52:46
【问题描述】:

想象一下我有这个数据框:

position    coverage
   1           30
   2            2
   3            1
   4            8
   5            2
   6            3
   7            20
   8            40
   .             .
   .             .
  100            0
  101            2
  102            3
  103            4
  104            1
  105           40

我想获得那些至少有 4 个位置的覆盖率低于 10 值的区域。

在这种情况下,我想要的输出是:

start      end
  2         6
 100       104 

我正在尝试一个 for 循环,但我不知道如何构建它来处理一组行而不是逐行。 你知道我怎样才能实现这个输出吗?

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以从data.table 使用rleid。根据'coverage'值小于10创建分组索引,子集'position'行数大于或等于4且'coverage'的all小于10,然后使用'grp ' 来获取 'position' 的 firstlast 元素

    library(data.table)
    setDT(df1)[, position[.N >=4 & all(coverage < 10)],
             .(grp = rleid(coverage < 10))][,
          .(start = first(V1), end = last(V1)), grp][, grp := NULL][]
    #    start end
    #1:     2   6
    #2:   100 104
    

    dplyr

    library(dplyr)
    df1 %>% 
       group_by(grp = rleid(coverage < 10)) %>% 
       filter(all(coverage < 10), n() >=4) %>% 
       group_by(grp) %>% 
       summarise(start = first(position), end = last(position)) %>% 
       select(-grp)
    

    或与rle 来自base R

    rl <- rle(df1$coverage < 10)
    do.call(rbind, lapply(split(df1$position,
       rep(seq_along(rl$values), rl$lengths)), range)[rl$values & rl$lengths >= 4])
    

    数据

    df1 <- structure(list(position = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 100L, 
    101L, 102L, 103L, 104L, 105L), coverage = c(30L, 2L, 1L, 8L, 
    2L, 3L, 20L, 40L, 0L, 2L, 3L, 4L, 1L, 40L)), class = "data.frame", 
    row.names = c(NA, 
    -14L))
    

    【讨论】:

      猜你喜欢
      • 2019-12-22
      • 1970-01-01
      • 2021-01-28
      • 2022-08-22
      • 2014-01-25
      • 1970-01-01
      • 2023-03-10
      • 2014-09-13
      • 1970-01-01
      相关资源
      最近更新 更多