在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 referenceTablefoverlaps正常运行所必需),然后仅选择第一个联接就运行一个简单的重叠联接,因为您想要任何联接(我已使用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

08-05 23:57