我想折叠以下数据框
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折叠,其中连续行上的gain,loss,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
我不知道如何使用聚合函数执行此操作,并希望得到任何帮助。谢谢!
答案 0 :(得分:5)
您可以使用unique
包中的data.table
进行一些修改:
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
答案 1 :(得分:4)
你可以尝试
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关于非重叠比赛的评论,一种解决方法是:
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))
答案 2 :(得分:1)
由于您有基因组拷贝数数据,您可以考虑使用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
记得它是如何拆分的话会更好。现在正在努力。