我想在我的数据集中创建新列,其值由另一个数据集中的值确定,但它并不像一列中的值是另一列中值的函数那么简单。这是一个例子:
>df1
chromosome position
1 1 1
2 1 2
3 1 4
4 1 5
5 1 7
6 1 12
7 1 13
8 1 15
9 1 21
10 1 23
11 1 24
12 2 1
13 2 5
14 2 7
15 2 8
16 2 12
17 2 15
18 2 18
19 2 21
20 2 22
和
>df2
chromosome segment_start segment_end segment.number
1 1 1 5 1.1
2 1 6 20 1.2
3 1 21 25 1.3
4 2 1 7 2.1
5 2 8 16 2.2
6 2 18 22 2.3
我想在df1中创建一个名为'segment'的新列,并且segment中的值将由哪个段(由'segment_start','segment_end'和来自df2的'chromosome'确定)确定在'位置'属于。例如,在df1,第7行,位置= 13,染色体= 1。因为13在6到20之间,我假设的“段”列中的条目将是df2的第2行的1.2,因为13位于该行的segment_start和segment_end之间(分别为6和20),以及'染色体'来自df1第7行的值为1,正如df2第2行中的“染色体”为1。
df1中的每一行都属于df2中描述的一个段;也就是说,它与一个片段位于同一染色体上,并且其“位置”是> = segment_start和< = segment_end。我希望将这些信息输入df1,因此它表示每个位置属于哪个段。
我正在考虑使用if函数,并以:
开头if(df1$position>=df2$segment_start & df1$position<=df2$segment_end & df1$chromosome==df2$chromosome) df1$segment<-df2$segment.number
但我不确定这种方式是否可行。如果没有其他可能代码可以帮助说明我正在尝试做什么。基本上,我想通过它的位置和染色体将每一行匹配到df2中的一个段。感谢。
答案 0 :(得分:2)
这似乎是滚动连接。您可以将data.table
用于此
require(data.table)
DT1 <- data.table(df1, key = c('chromosome','position'))
DT2 <- data.table(df2, key = c('chromosome','section_start'))
# this will perform the join you want (but retain all the
# columns with names names of DT2)
# DT2[DT1, roll=TRUE]
# which is why I have renamed and subset here)
DT2[DT1, roll=TRUE][ ,list(chromosome,position = segment_start,segment.number)]
# chromosome position segment.number
# 1: 1 1 1.1
# 2: 1 2 1.1
# 3: 1 4 1.1
# 4: 1 5 1.1
# 5: 1 7 1.2
# 6: 1 12 1.2
# 7: 1 13 1.2
# 8: 1 15 1.2
# 9: 1 21 1.3
# 10: 1 23 1.3
# 11: 1 24 1.3
# 12: 2 1 2.1
# 13: 2 5 2.1
# 14: 2 7 2.1
# 15: 2 8 2.2
# 16: 2 12 2.2
# 17: 2 15 2.2
# 18: 2 18 2.3
# 19: 2 21 2.3
# 20: 2 22 2.3
答案 1 :(得分:1)
您真的需要查看Bioconductor的GenomicRanges包。它提供了适合您的用例的数据结构。
首先,我们创建GRanges
个对象:
gr1 <- with(df1, GRanges(chromosome, IRanges(position, width=1L)))
gr2 <- with(df2, GRanges(chromosome, IRanges(segment_start, segment_end),
segment.number=segment.number))
然后我们找到重叠并进行合并:
hits <- findOverlaps(gr1, gr2)
gr1$segment[queryHits(hits)] <- gr2$segment.number[subjectHits(hits)]
答案 2 :(得分:0)
我将假设df2
中的区域不重叠,连续且完整(不会遗漏df1
中的任何位置)。每当我尝试时,我似乎都会这样做,所以这是我最新的想法。
首先,确保染色体是两个数据集中的一个因素
df1$chromosome<-factor(df1$chromosome)
df2$chromosome<-factor(df2$chromosome)
现在我想打开chr / pos到一个通用位置,我会用
做到这一点ends<-with(df2, tapply(segment_end, chromosome, max))
offset<-head(c(0,cumsum(ends)),-1)
names(offset)<-names(ends)
这为所有染色体上的所有位置分配了唯一的位置值,并且它跟踪了这个新系统中每条染色体开头的偏移量。现在我们将根据df2
seglookup <- approxfun(with(df2, offset[chromosome]+segment_start), 1:nrow(df2),
method="constant", rule=2)
我们使用approxfun
在每个片段的遗传位置空间中找到正确的间隔。现在我们在df1
segid <- with(df1, seglookup(offset[chromosome]+position))
现在我们为每个职位提供了正确的ID。我们可以通过合并数据并查看结果来验证这一点
cbind(df1, df2[segid,-1])
chromosome position segment_start segment_end segment.number
1 1 1 1 5 1.1
2 1 2 1 5 1.1
3 1 4 1 5 1.1
4 1 5 1 5 1.1
5 1 7 6 20 1.2
6 1 12 6 20 1.2
7 1 13 6 20 1.2
8 1 15 6 20 1.2
9 1 21 21 25 1.3
10 1 23 21 25 1.3
11 1 24 21 25 1.3
12 2 1 1 7 2.1
13 2 5 1 7 2.1
14 2 7 1 7 2.1
15 2 8 8 16 2.2
16 2 12 8 16 2.2
17 2 15 8 16 2.2
18 2 18 18 22 2.3
19 2 21 18 22 2.3
20 2 22 18 22 2.3
所以看起来我们没事。