按相似行折叠数据框
collapse dataframe by similar rows
我想折叠以下数据框
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
我想折叠每个字符,其中连续行的增益、损失、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
我不确定如何使用聚合函数执行此操作,希望得到任何帮助。谢谢!
你可以试试
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))
您可以使用 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
由于您有基因组拷贝数数据,您可能会考虑使用来自 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
记得它是如何拆分的就更好了。现在正在努力。
我想折叠以下数据框
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
我想折叠每个字符,其中连续行的增益、损失、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
我不确定如何使用聚合函数执行此操作,希望得到任何帮助。谢谢!
你可以试试
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))
您可以使用 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
由于您有基因组拷贝数数据,您可能会考虑使用来自 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
记得它是如何拆分的就更好了。现在正在努力。