由于我对 previous question 的糟糕执行和解释,我将重新开始并尝试尽可能简短和概括地提出问题。

我有两个数据框(见下面的例子)。每个数据集包含相同数量的列。

tc <- textConnection('
ID  Track1  Track2  Track3  Track4  Time    Loc
4   15      ""      ""      50      40      1
5   17      115     109     55      50      1
6   17      115     109     55      60      1
7   13      195     150     60      70      1
8   13      195     150     60      80      1
9   ""      ""      181     70      90      2 #From this row, example data added
10  ""      ""      182     70      92      2
11  429     31      ""      80      95      3
12  480     31      12      80      96      3
13  118     ""      ""      90      100     4
14  120     16      213     90      101     4
')

MATCHINGS <- read.table(tc, header=TRUE)

tc <- textConnection('
ID  Track1  Track2  Track3  Track4  Time    Loc
""  15      ""      ""      50      40      1
""  17      ""     109      55      50      1
""  17      432    109      55      65      1
""  17      115     109     55      59      1
""  13      195     150     60      68      1
""  13      195     150     60      62      1
""  10      5       1       10      61      3
""  13      195     150     60      72      1
""  40      ""      181     70      82      2 #From this row, example data added
""  ""      ""      182     70      85      2
""  429     ""      ""      80      90      3
""  ""      31      12      80      92      3
""  ""      ""      ""      90      95      4
""  118     16      213     90      96      4
')

INVOLVED <- read.table(tc, header=TRUE)

目标是通过将 MATCHINGSINVOLVEDTrack1 进行匹配,将 Track4 中最近的 ID 放入 Loc 中。一个额外的条件是匹配的 Time 条目的 INVOLVED 不能高于 Time 条目的 MATCHING 。此外,Track1 上的匹配是最优选的,Track4 上的匹配是最不优选的。然而,只有 Track4 始终可用(所有其他 Track 列可以为空)。因此,预期的结果是:
ID Track1 Track2 Track3 Track4 Time Loc
4     15     ""     ""     50   40   1
5     17     ""    109     55   50   1
""    17    432    109     55   65   1
6     17    115    109     55   59   1
7     13    195    150     60   68   1
7     13    195    150     60   62   1
""    10      5      1     10   61   3
8     13    195    150     60   72   1
9     40     ""    181     70   82   2 #From this row, example data added
10    ""     ""    182     70   85   2
11    429    ""     ""     80   90   3
12    ""     31     12     80   92   3
13    ""     ""     ""     90   95   4
13    118    16    213     90   96   4

我尝试使用 data.table 包进行此操作,但未能有效执行此操作。是否有可能摆脱矢量扫描并有效地遍历数据而不循环?
dat <- data.table(MATCHINGS)
for(i in 1:nrow(INVOLVED)){
    row <- INVOLVED[i,]
    match <- dat[Time>=row$Time][Loc==row$Loc][Track4==row$Track4][Track4!=""][order(Time)][1]
    if(!is.na(match$ID)){ INVOLVED$ID[i]<-match$ID }
    match <- dat[Time>=row$Time][Loc==row$Loc][Track3==row$Track3][Track3!=""][order(Time)][1]
    if(!is.na(match$ID)){ INVOLVED$ID[i]<-match$ID }
    match <- dat[Time>=row$Time][Loc==row$Loc][Track2==row$Track2][Track2!=""][order(Time)][1]
    if(!is.na(match$ID)){ INVOLVED$ID[i]<-match$ID }
    match <- dat[Time>=row$Time][Loc==row$Loc][Track1==row$Track1][Track1!=""][order(Time)][1]
    if(!is.na(match$ID)){ INVOLVED$ID[i]<-match$ID }
}

更新

更新了显示需要 Track 1 to 3 的示例数据。如图所示,Track1 最重要,Track4 最不重要。即使 Track1 to 3 匹配 MATCHINGS x 并且 Track4 匹配 MATCHINGS yIDy 也应该分配给那个 INVOLVED row 。所以:Track3 匹配覆盖 Track4 匹配,Track2 匹配覆盖 Track3 匹配,Track1 匹配覆盖 Track2 匹配。

最佳答案

随着 roll 参数还能够将下一个观察结果与新的 ( v1.9.6+ ) on= 参数一起向后滚动,我们可以更直接地做到这一点:

require(data.table)
setDT(MATCHINGS)
setDT(INVOLVED)
INVOLVED[ , ID := MATCHINGS[INVOLVED, ID, roll=-Inf,
                    mult="first", on=c("Loc", "Track4", "Time")]]]

就是这样。

这是一个 data.table -ish 开始。这仅使用 Track 4(而不是 1 到 3),但它似乎仍会产生请求的输出。
M = as.data.table(MATCHINGS)
I = as.data.table(INVOLVED)
M[,Time:=-Time]
I[,Time:=-Time]
setkey(M,Loc,Track4,Time)
I[,ID:={i=list(Loc,Track4,Time);M[i,ID,roll=TRUE,mult="first"]}][,Time:=-Time]

    ID Track1 Track2 Track3 Track4 Time Loc
 1:  1     NA    105     NA     35    1   1
 2:  1     NA     NA     NA     35    2   1
 3:  1     26    105     NA     35    3   1
 4:  2     NA     NA     NA     40   20   1
 5:  2    134      1      6     40   20   1
 6:  3     13    109     NA     45   30   1
 7:  4     15     NA     NA     50   40   1
 8:  5     17     NA    109     55   50   1
 9: NA     17    432    109     55   65   1
10:  6     17    115    109     55   59   1
11:  7     13    195    150     60   68   1
12:  7     13    195    150     60   62   1
13: NA     10      5      1     10   61   3
14:  8     13    195    150     60   72   1

有趣的问题!如果这看起来没问题,请将示例数据更改为需要轨道 1 到 3。或者您可以从这里获取它。

关于r - 组合 data.table 中的一组条件以使用二分搜索提取值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12723182/

10-12 17:18