我有一个遗传数据集,我想对基因组中物理上接近的遗传变异/行进行分组。我想对每个染色体(染色体
)基因组中某些斑点范围内的基因进行分组。
我的“spots”数据集包含变量/行需要在一定范围内的位置,如下所示:
chrom low high
1 500 1700
1 19500 20600
5 400 1500
我的< code>low和< code>high列是我希望查看下一个数据集中是否有任何行落入其中的范围,同时考虑到染色体(< code>chrom)也必须匹配。具有唯一范围和chrom组合的每一行都是它自己的组,我正在查看我的另一个数据集中是否有任何内容属于该组。
我的另一个数据集有一个位置值,我正在查看它是否符合上面的任何范围,匹配<code>chrom,以便将其标记为对应于该范围,然后我可以将相同范围和chrom中的位置分组在一起:
Gene chrom position
Gene1 1 1200
Gene2 1 10000
Gene3 5 500
Gene4 5 560
Gene5 1 20100
我曾尝试使用<code>group_by())。
输出如下所示:
Gene chrom position Group
Gene1 1 1200 1 #position is in one of the ranges and matches the chrom so is in a group
Gene2 1 10000 NA #does not fit into any range on chrom 2 (no matches)
Gene3 5 500 2 #position is in one of the ranges and matches the chrom so is in a group
Gene4 5 560 2 #position is in the same range and chrom as above so joins that group
Gene5 1 20100 3 #position matches a chrom and range and so gets a group corresponding to that particular chrom and range
chrom
上,但它们确实匹配chrom并且在我的第一个数据集的第3行的范围内-因此它们可以在对应于该范围和chrom的组中。chrom
,它们在low
和high
的不同范围内,因此获取自己的组为唯一的范围。因此,我创建了一个< code>Group列,对于同一< code>chrom上的< code>low和< code>high之间的同一范围内的所有行,如果它们的位置在第一个数据集中的任何范围和chrom中都不匹配,则为NA。
输入数据:
df1 <-
structure(list(chrom = c(1L, 1L, 5L),
low = c(500L, 19500L, 400L), high = c(1700L, 20600L, 1500L
)), row.names = c(NA, -3L), class = c("data.table", "data.frame"))
df2 <-
structure(list(Gene = c("Gene1", "Gene2", "Gene3", "Gene4", "Gene5"
), chrom = c(1L, 1L, 5L, 5L, 1L), position = c(1200L, 10000L,
500L, 560L, 20100L)), row.names = c(NA, -5L), class = c("data.table",
"data.frame"))
我还在考虑为每个唯一范围和 chrom 组合为我的第一个数据集提供唯一标识符,然后将该标识符分配给数据集 2 中与该组合匹配的任何行,以便该标识符创建我的组编号列。虽然我的真实数据是2.3k行的范围和82k行以匹配到共享组中,所以我在运行我通常会尝试的dplyr选项时也遇到了问题。
匿名用户
正如注释中所指出的,您只需使用< code>GenomicRanges中的< code>findOverlaps来查找包含第二个data.frame中行的参考数据帧中的行
您的df2与示例中显示的有点不同,因此我将其更改为匹配:
df2 = structure(list(Gene = c("Gene1", "Gene2", "Gene3", "Gene4", "Gene5"
), chrom = c(1L, 1L, 5L, 5L, 1L), position = c(1200L, 10000L,
500L, 560L, 20100L)), row.names = c(NA, -5L), class = c("data.table",
"data.frame"))
你的 df1 有不同的顺序:
chrom min max low high
1 1 1000 1200 500 1700
2 1 20000 20100 19500 20600
3 5 900 1000 400 1500
我们可以制作一个GenomicRanges对象,如下所示:
library(GenomicRanges)
gr1 = makeGRangesFromDataFrame(df1,start.field="low",end.field="high")
gr1$Group = 1:length(gr1)
GRanges object with 3 ranges and 1 metadata column:
seqnames ranges strand | Group
<Rle> <IRanges> <Rle> | <integer>
[1] 1 500-1700 * | 1
[2] 1 19500-20600 * | 2
[3] 5 400-1500 * | 3
然后对第二个数据帧执行同样的操作并找到重叠:
gr2 = makeGRangesFromDataFrame(df2,start.field="position",end.field="position")
ovlp = as.data.frame(findOverlaps(gr2,gr1))
df2$Group = ovlp$subjectHits[match(1:length(gr2),ovlp$queryHits)]
Gene chrom position Group
1 Gene1 1 1200 1
2 Gene2 1 10000 NA
3 Gene3 5 500 3
4 Gene4 1 560 1
5 Gene5 1 20100 2
如果您了解sql,
那么可以在sql R中快速解决此问题:
df1$group_id <- seq(nrow(df1)) #This creates the unique groups for each interval
sqldf::sqldf('
SELECT df2.*, df1.group_id
FROM df2
LEFT JOIN df1
ON df2.chrom = df1.chrom AND position between low AND high')
Gene chrom position group_id
1 Gene1 1 1200 1
2 Gene2 1 10000 NA
3 Gene3 5 500 3
4 Gene4 5 560 3
5 Gene5 1 20100 2
您可以在< code>data.table中使用非对等联接:
library(data.table)
df1 <- setDT(df1)
df2 <- setDT(df2)
df1[,group := 1:.N]
df1[df2,on = .(chrom, low < position, high > position)]
chrom low high group Gene
1: 1 1200 1200 1 Gene1
2: 1 10000 10000 NA Gene2
3: 5 500 500 3 Gene3
4: 5 560 560 3 Gene4
5: 1 20100 20100 2 Gene5
在这里,我首先为df1
的每一行设置一个组。合并后,如果满足条件,则该行将与组相关联。
非均衡合并不是超级直观的,而是超级强大和明确的:合并条件<code>。(色度,低
在data.table
中,当你这样做时
df1[df2,on = something]
您用满足在
上表示的条件的df2
行子集df1
。如果某事
只是df1
和df2
的公共变量,那么它等价于
merge(df1,df2,all.y = T,by = "someting")
但是,某些内容
可以是两个 data.表中的变量之间的变量和条件的列表。此处,.()
表示列表,.(铬,低
使用不等式的非等比合并的输出替换了主数据不等式中表示的变量。表(即,
df1
)中的变量。表(即这里的df2
),因此low
和high
成为位置
。如果要保持<code>低
您实际上可以进行相反的合并,我们通过
df1
条目子集df2
,条件相同:
df2[df1,on = .(chrom,position >low , position<high)]
Gene chrom position position.1 group
1: Gene1 1 500 1700 1
2: Gene5 1 19500 20600 2
3: Gene3 5 400 1500 3
4: Gene4 5 400 1500 3
在这里,您将
上df1
子集为df2
的条目,这些条目满足 = .()中表示的条件,并获得实际上属于一个组的
Gene
列表(Gene2
不在这里,因为它与子集不匹配)。
与上面解释的类似,这里<code>位置<code>变为<code>低<code>和<code>高<code>
我刚刚看到了@DavidArenburg的评论,这是我建议和解释的更简洁和更好的版本:
df2[, grp := df1[.SD, which = TRUE, on = .(chrom, low <= position, high >= position)]]
直接关联非等式合并
的结果 df1[df2,on = .(铬,低
问题内容: 我有一个表,其中包含开始时间(在示例中使用数字以使其保持简单)以及事件的持续时间。 我想确定“块”及其开始时间和结束时间。 每当前一行的结束时间(开始时间+持续时间)(按开始时间排序)与当前行的开始时间之间的差值为时,应开始一个新的“块”。 这是我的测试数据,包括在注释中尝试进行图形解释的尝试: 第一个块开始于,结束于。由于与下一行的区别是,开始另一个块,终止于。 我可以使用来识别块的
问题内容: 我有一个包含类别,日期和费率的表。每个类别在不同日期可以具有不同的费率,一个类别在给定日期只能具有一个费率。 唯一索引(类别,日期,费率)我希望针对每个类别将所有连续的日期范围归为一组,并仅保留范围的开始和结束。对于前面的示例,我们将有: 我在论坛中找到了一个类似的解决方案,但并未完全给出结果 请参见SQL FIDDLE 如何在mysql中做同样的事情?请帮忙! 问题答案: MySQL
问题内容: 假设我有一个带有数字列的表(我们称其为“分数”)。 我想生成一个计数表,该表显示每个范围内得分出现的次数。 例如: 在此示例中,分数在0到9之间的行有11行,分数在10到19之间的行有14行,分数在20-29范围内的行有3行。 有一个简单的方法来设置它吗?您有什么推荐的吗? 问题答案: 在SQL Server 2000上,投票率最高的答案均不正确。也许它们使用的是其他版本。 这是它们在
我有一个蜂巢表2columns.EmployeeID和工资。 数据如下所示。 我想根据薪金列创建分区。例如划分为10000到20000,20001到30000的工资范围。 我如何实现这一点。
我是sql新手,我有一个postgresql数据库,它有: 表 我只需要从db|name1|name3获取3行 数据库有300000多行。 我尝试使用: 我得到了 但是如何在每个组中添加任何名称3在SQL和django orm中最好的方法是什么?
问题内容: 所以,我有一张表,上面有这样的行: 每次扫描警报时(即每次触发或清除警报时)都会添加“已扫描的警报”行。任何警报都会添加带有特定Ev_Custom1的行。第一列Ev_Message包含一个计算机ID,该ID使我可以将警报与其他计算机分开。(您不喜欢任意的列名吗?)超过900条独特的警报消息。 我希望查询返回的内容是这样的: 这将是两个日期之间过滤的查询。我可以更改进入表的数据,但是有9