我有一组非重叠的区间,每个区间都有一个ID。给定一个数字,我想根据它所属的间隔给它分配一个ID(如果不存在这样的间隔,则为NA)。
intervals_id <- structure(list(ID = c(851, 852, 999), Lower = c(85101, 85201,
85301), Upper = c(85104, 85206, 85699)), .Names = c("ID", "Lower",
"Upper"), row.names = c(NA, -3L), class = "data.frame")
# ID Lower Upper
# 1 851 85101 85104
# 2 852 85201 85206
# 3 999 85301 85699
value <- c(15555, 85102, 85201, 85206, 85207, 85600, 86999)
我使用cut
组合了一些内容,它似乎有效,但感觉很麻烦。想要更优雅,更直接的解决方案吗?
intervals_id <- intervals_id[order(intervals_id$Lower),]
intervals_id$UpperP <- intervals_id$Upper + 0.01
position <- as.numeric(cut(value, breaks =
as.numeric(t(as.matrix(intervals_id[,c("Lower", "UpperP")]))), right = FALSE))
position[position %% 2 == 0] <- NA
position <- (position + 1) %/% 2
# desired result
data.frame(value, valueID = intervals_id$ID[position])
# value valueID
# 1 15555 NA
# 2 85102 851
# 3 85201 852
# 4 85206 852
# 5 85207 NA
# 6 85600 999
# 7 86999 NA
答案 0 :(得分:2)
您可以使用data.table
包中的foverlaps()
功能。它找到两组间隔之间的重叠。
首先,我们需要创建data.table并为它们设置密钥。
library(data.table)
# Using OPs data
setDT(intervals_id)
setkey(intervals_id, Lower, Upper)
# Create dummy intervals (same coordinate) and set key
valueDT <- data.table(start = value, end = value)
setkey(valueDT, start, end)
接下来,应用foverlaps()
功能:
foverlaps(valueDT, intervals_id)[, .(value = start, ID)]
结果:
# value ID
# 1: 15555 NA
# 2: 85102 851
# 3: 85201 852
# 4: 85206 852
# 5: 85207 NA
# 6: 85600 999
# 7: 86999 NA
PS。 foverlaps
输出如下所示:
ID Lower Upper start end
1: NA NA NA 15555 15555
2: 851 85101 85104 85102 85102
3: 852 85201 85206 85201 85201
4: 852 85201 85206 85206 85206
5: NA NA NA 85207 85207
6: 999 85301 85699 85600 85600
7: NA NA NA 86999 86999
如果需要,您可以使用foverlaps
个选项。
nomatch
过滤掉没有重叠的间隔mult
报告“全部”,“第一次”或“最后”重叠答案 1 :(得分:2)
使用data.table
的另一个baseR
- data.table::between
混合使用
sapply(value, function(i) {i1 = df$ID[data.table::between(i, df$Lower, df$Upper)];
if (length(i1) == 0){NA}else{i1}})
#[1] NA 851 852 852 NA 999 NA