【问题标题】:collapse dataframe by similar rows按相似行折叠数据框
【发布时间】:2015-03-12 21:09:22
【问题描述】:

我想折叠以下数据框

df

chr start    stop        gain loss pvalue_gain pvalue_loss
6 68838806   68857819    0    6    1.00000000  0.05105438
9 29779560   29788411    5    1    0.02320654  1.00000000
9 29788411   29809428    5    1    0.02320654  1.00000000
9 29809428   29831788    5    1    0.02320654  1.00000000
9 29831788   29899917    4    1    0.05145798  1.00000000
10   650294    727180    7    0    0.07759025  1.00000000

我想折叠每个 chr,其中连续行上的增益、损失、pvalue_gain 和 pvalue_loss 数字相同。但是,对于数据框折叠时的这些连续行,我想使用这些连续行的第一行的起始编号和这些连续行的最后一个停止编号。

例如-

chr start    stop        gain loss pvalue_gain pvalue_loss
9 29779560   29788411    5    1    0.02320654  1.00000000
9 29788411   29809428    5    1    0.02320654  1.00000000
9 29809428   29831788    5    1    0.02320654  1.00000000

将折叠为

chr start    stop        gain loss pvalue_gain pvalue_loss
9 29779560   29831788    5    1    0.02320654  1.00000000

最终输出:

chr start    stop        gain loss pvalue_gain pvalue_loss
6 68838806   68857819    0    6    1.00000000  0.05105438
9 29779560   29831788    5    1    0.02320654  1.00000000
9 29831788   29899917    4    1    0.05145798  1.00000000
10   650294    727180    7    0    0.07759025  1.00000000

我不确定如何使用聚合函数来执行此操作,希望能提供任何帮助。谢谢!

【问题讨论】:

    标签: r bioinformatics collapse reshape


    【解决方案1】:

    您可以使用 data.table 包中的 unique 并进行一些修改:

    library(data.table)
    unique(as.data.table(df)[, stop := stop[.N], 
                               key = .(gain, loss, pvalue_gain, pvalue_loss)])
    
    #    chr    start     stop gain loss pvalue_gain pvalue_loss
    # 1:   6 68838806 68857819    0    6  1.00000000  0.05105438
    # 2:   9 29831788 29899917    4    1  0.05145798  1.00000000
    # 3:   9 29779560 29831788    5    1  0.02320654  1.00000000
    # 4:  10   650294   727180    7    0  0.07759025  1.00000000
    

    【讨论】:

    • 这文字写得真好!
    • @DavidArenburg 您可能还需要纠正不相邻的范围,也许是foverlaps
    【解决方案2】:

    你可以试试

    library(data.table)
    setDT(df)[,list(chr=chr[1], start=start[1], stop=stop[.N]) ,
                     by=list(gain, loss, pvalue_gain, pvalue_loss)]
    

    或使用dplyr

    library(dplyr)
    df %>% 
       group_by(gain, loss, pvalue_gain, pvalue_loss) %>% 
       summarise(chr=chr[1], start=start[1], stop=stop[n()])
    

    更新

    根据@Michael Lawrence 关于非重叠匹配的cmets,纠正此问题的一种方法是:

    setDT(df)[, .ind:= cumsum(c(TRUE,start[-1]!=stop[-.N])),
            list(gain, loss, pvalue_gain, pvalue_loss)][,
           list(chr=chr[1], start=start[1], stop=stop[.N]),
           list(gain, loss, pvalue_gain, pvalue_loss, .ind)][,.ind:=NULL][]
    #    gain loss pvalue_gain pvalue_loss chr    start     stop
    #1:    0    6       1.000       0.051   6 68838806 68857819
    #2:    5    1       0.023       1.000   9 29779560 29831788
    #3:    5    1       0.023       1.000   9 29831815 29831841
    #4:    4    1       0.051       1.000   9 29831788 29899917
    #5:    7    0       0.078       1.000  10   650294   727180
    

    新数据

    df <- structure(list(chr = c(6L, 9L, 9L, 9L, 9L, 9L, 10L), start = 
    c(68838806L, 29779560L, 29788411L, 29809428L, 29831815L, 29831788L, 650294L
    ), stop = c(68857819L, 29788411L, 29809428L, 29831788L, 29831841L, 
    29899917L, 727180L), gain = c(0L, 5L, 5L, 5L, 5L, 4L, 7L), loss = c(6L, 
    1L, 1L, 1L, 1L, 1L, 0L), pvalue_gain = c(1, 0.02320654, 0.02320654, 
    0.02320654, 0.02320654, 0.05145798, 0.07759025), pvalue_loss = c(0.05105438, 
    1, 1, 1, 1, 1, 1)), .Names = c("chr", "start", "stop", "gain", 
    "loss", "pvalue_gain", "pvalue_loss"), class = "data.frame", row.names = c(NA, 
    -7L))
    

    【讨论】:

    • 真的吗?在我看来,setDT 可能会慢一点,因为它必须先弄清楚输入是什么,然后再进行“设置”。 as.data.table 将简单地为正在处理的对象调用相关的method。不过我从来没有检查过。
    • @docendodiscimus,just asked Arun。差不多就是这样。
    • 您确定这是折叠连续值吗?看起来它正在因增益、损失和 p 值的任何独特组合而崩溃,这看起来并不完全相同。
    • @MichaelLawrence 你能举一个例子,这不会得到预期的输出吗?谢谢。在这里,我按照您提到的那些变量进行分组,并通过获取 (chr, start) 的第一个元素和 stop 的最后一个元素来对数据集进行子集化。
    • 他想要的是减少相邻的范围。可能有不相邻的范围具有相同的增益、损失等组合。
    【解决方案3】:

    由于您有基因组拷贝数数据,您可能会考虑使用 Bioconductor 的 GenomicRanges 包。您可以定义一个名为 GRanges 的对象,它正式表示数据的语义,因此能够为典型用例提供方便高效的功能。

    这里我们构造GRanges对象:

    gr <- makeGRangesFromDataFrame(df)
    

    现在我认为你真正想要做的是在拷贝数值相同时减少相邻范围。所以我们只需要按拷贝数值对数据进行分组:

    grl <- split(gr, as.list(df[c("gain", "loss", "pvalue_gain", "pvalue_loss")]))
    

    as.list 是必需的,因为方法包中存在错误。无论如何,我们然后减少相邻的范围并结转这些值:

    reduced <- unlist(reduce(grl))
    values(reduced) <- values(unlist(phead(grl, 1L)))
    

    最后一行有点复杂。如果GRangesList 记得它是如何拆分的,那就更好了。现在正在努力。

    【讨论】:

    • 在GRanges对象构造之前使用这个-df$seqnames
    猜你喜欢
    • 2013-12-13
    • 2018-09-25
    • 2016-06-07
    • 2017-09-16
    • 2022-01-13
    • 2016-07-07
    • 2019-01-20
    • 2021-11-08
    • 2012-10-04
    相关资源
    最近更新 更多