gpt4 book ai didi

r - 组合 data.table 中的条件集以使用二进制搜索提取值

转载 作者:行者123 更新时间:2023-12-04 09:32:07 25 4
gpt4 key购买 nike

自从我对 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)

目标是放置最近的 ID 来自 MATCHINGS进入INVOLVED通过匹配 Track1Track4Loc .一个额外的条件是 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 xTrack4匹配 MATCHINGS y , IDy应该分配给那个 INVOLVED row .所以:Track3匹配覆盖 Track4匹配,Track2匹配覆盖 Track3匹配,Track1匹配覆盖 Track2匹配。

最佳答案

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

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

就是这样。


这是一个 data.table 风格的开始。这仅使用轨道 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com