【问题标题】:Collapsing a data.frame by group and interval coordinates按组和间隔坐标折叠 data.frame
【发布时间】:2019-08-16 02:25:06
【问题描述】:

我有一个data.frame,它指定线性区间(沿染色体),其中每个区间都分配给一个组:

df <- data.frame(chr = c(rep("1",5),rep("2",4),rep("3",5)),
                 start = c(seq(1,50,10),seq(1,40,10),seq(1,50,10)),
                 end = c(seq(10,50,10),seq(10,40,10),seq(10,50,10)),
                 group = c(c("g1.1","g1.1","g1.2","g1.3","g1.1"),c("g2.1","g2.2","g2.3","g2.2"),c("g3.1","g3.2","g3.2","g3.2","g3.3")),
                 stringsAsFactors = F)

我正在寻找一种快速的方法来折叠 dfchrgroup 以便沿着分配给相同 groupchr连续间隔组合起来,它们的startend 坐标也相应修改。

这是此示例的预期结果:

res.df <- data.frame(chr = c(rep("1",4),rep("2",4),rep("3",3)),
                     start = c(c(1,21,31,41),c(1,11,21,31),c(1,11,41)),
                     end = c(c(20,30,40,50),c(10,20,30,40),c(10,40,50)),
                     group = c("g1.1","g1.2","g1.3","g1.1","g2.1","g2.2","g2.3","g2.2","g3.1","g3.2","g3.3"),
                     stringsAsFactors = F)

【问题讨论】:

    标签: r dataframe datatable dplyr aggregate


    【解决方案1】:

    不同的tidyverse 方法可能是:

    df %>%
     gather(var, val, -c(chr, group)) %>%
     group_by(chr, group) %>%
     filter(val == min(val) | val == max(val)) %>%
     spread(var, val)
    
      chr   group   end start
      <chr> <chr> <dbl> <dbl>
    1 1     g1.1     20     1
    2 1     g1.2     30    21
    3 1     g1.3     50    31
    4 2     g2.1     10     1
    5 2     g2.2     20    11
    6 2     g2.3     40    21
    7 3     g3.1     10     1
    8 3     g3.2     40    11
    9 3     g3.3     50    41
    

    或者:

    df %>%
     group_by(chr, group) %>%
     summarise_all(funs(min, max)) %>%
     select(-end_min, -start_max)
    
      chr   group start_min end_max
      <chr> <chr>     <dbl>   <dbl>
    1 1     g1.1          1      20
    2 1     g1.2         21      30
    3 1     g1.3         31      50
    4 2     g2.1          1      10
    5 2     g2.2         11      20
    6 2     g2.3         21      40
    7 3     g3.1          1      10
    8 3     g3.2         11      40
    9 3     g3.3         41      50
    

    使用rleid()data.table 更新帖子的解决方案可能是:

    df %>%
     group_by(chr, group, group2 = rleid(group)) %>%
     summarise_all(funs(min, max)) %>%
     select(-end_min, -start_max)
    
       chr   group group2 start_min end_max
       <chr> <chr>  <int>     <dbl>   <dbl>
     1 1     g1.1       1         1      20
     2 1     g1.1       4        41      50
     3 1     g1.2       2        21      30
     4 1     g1.3       3        31      40
     5 2     g2.1       5         1      10
     6 2     g2.2       6        11      20
     7 2     g2.2       8        31      40
     8 2     g2.3       7        21      30
     9 3     g3.1       9         1      10
    10 3     g3.2      10        11      40
    11 3     g3.3      11        41      50
    

    【讨论】:

    • 谢谢@tmfmnk。我认为我之前的例子不够清楚,不幸的是你的回答并没有解决问题。
    【解决方案2】:

    编辑:为了考虑连续要求,您可以使用与之前相同的方法,但添加一个基于连续值的额外分组变量。

    library(dplyr)
    
    df  %>%
      group_by(chr, group, temp.grp = with(rle(group), rep(seq_along(lengths), lengths))) %>%
      summarise(start = min(start),
                end = max(end)) %>%
      arrange(chr, start) %>%
      select(chr, start, end, group)
    
    # A tibble: 11 x 4
    # Groups:   chr, group [9]
       chr   start   end group
       <chr> <dbl> <dbl> <chr>
     1 1         1    20 g1.1 
     2 1        21    30 g1.2 
     3 1        31    40 g1.3 
     4 1        41    50 g1.1 
     5 2         1    10 g2.1 
     6 2        11    20 g2.2 
     7 2        21    30 g2.3 
     8 2        31    40 g2.2 
     9 3         1    10 g3.1 
    10 3        11    40 g3.2 
    11 3        41    50 g3.3 
    

    【讨论】:

    • 谢谢@H 1。我认为我之前的例子不够清楚,不幸的是你的回答没有解决问题。
    猜你喜欢
    • 2019-04-12
    • 2021-09-25
    • 2018-12-24
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    相关资源
    最近更新 更多