在R中,如何最好地向量化此操作?
我有一个参考值表,下限(A)和上限(B)。
我也有一个值(X)表格,可以对照上表进行查询。
对于X的每个值,我需要确定它是否位于参考表中A和B的任何值之间。
为了演示以上内容,这是使用循环的解决方案:
#For Reproduceability,
set.seed(1);
#Set up the Reference and Lookup Tables
nref = 5; nlook = 10
referenceTable <- data.frame(A=runif(nref,min=0.25,max=0.5),
B=runif(nref,min=0.50,max=0.75));
lookupTable <- data.frame(X=runif(nlook),IsIn=0)
#Process for each row in the lookup table
#search for at least one match in the reference table where A <= X < B
for(x in 1:nrow(lookupTable)){
v <- lookupTable$X[x]
tmp <- subset(referenceTable,v >= A & v < B)
lookupTable[x,'IsIn'] = as.integer(nrow(tmp) > 0)
}
我正在尝试删除
for(x in .... )
组件,因为现实生活中的表有成千上万条记录。 最佳答案
我找不到确切的副本,因此这是使用data.table::foverlaps
的可能解决方案。首先,我们需要在lookupTable
中添加一列,以便在两边都创建边界。然后key
referenceTable
(foverlaps
正常运行所必需),然后仅选择第一个联接就运行一个简单的重叠联接,因为您想要任何联接(我已使用0^
来转换为二进制)因为您不想要实际的位置)
library(data.table)
setDT(lookupTable)[, Y := X] # Add an additional boundary column
setkey(setDT(referenceTable)) # Key the referenceTable data set
lookupTable[, IsIn := 0 ^ !foverlaps(lookupTable,
referenceTable,
by.x = c("X", "Y"),
mult = "first",
nomatch = 0L,
which = TRUE)]
# X IsIn Y
# 1: 0.2059746 0 0.2059746
# 2: 0.1765568 0 0.1765568
# 3: 0.6870228 1 0.6870228
# 4: 0.3841037 1 0.3841037
# 5: 0.7698414 0 0.7698414
# 6: 0.4976992 1 0.4976992
# 7: 0.7176185 1 0.7176185
# 8: 0.9919061 0 0.9919061
# 9: 0.3800352 1 0.3800352
# 10: 0.7774452 0 0.7774452