使用两个data.frames将值与多个条件匹配

使用两个data.frames将值与多个条件匹配,r,dataframe,merge,match,closest,R,Dataframe,Merge,Match,Closest,我是R方面的新手,需要一些帮助。 我有两个信息非常相似的数据帧。第一个数据帧包含航空公司误连接的信息,而另一个数据帧是同一航空公司的整个时间表。现在,我需要的是在misconnection data.frame中创建一个新的列,其中包括时刻表中的航班,可以替换过境途中延误的航班 我想要替换的航班需要满足一系列条件(在一定的时间范围内,需要是相同的工作日,需要飞往相同的目的地)。此外,我希望R选择距离中转站新到达时间最近(按时间)的航班(从misconnection data.frame) 错误连

我是R方面的新手,需要一些帮助。 我有两个信息非常相似的数据帧。第一个数据帧包含航空公司误连接的信息,而另一个数据帧是同一航空公司的整个时间表。现在,我需要的是在misconnection data.frame中创建一个新的列,其中包括时刻表中的航班,可以替换过境途中延误的航班

我想要替换的航班需要满足一系列条件(在一定的时间范围内,需要是相同的工作日,需要飞往相同的目的地)。此外,我希望R选择距离中转站新到达时间最近(按时间)的航班(从misconnection data.frame)

错误连接data.frame如下所示(总共1620行):


好吧,这不太好,但你有一个相当复杂的问题,我不完全清楚这是否提供了你想要的-你需要在一个比你提供的小示例更大的数据集上检查它,以确保首先

# setup
library(data.table)
setDT(tt)
setDT(miscon)

# make tt long format splitting weekdays out
tt <- melt(tt[, paste("V", 1:7, sep = "") := tstrsplit(weekday, "")][, -"weekday"], measure.vars = paste("V", 1:7, sep = ""))[value != "."][, c("weekday", "value", "variable") := .(value, NULL, NULL)]

# join, calculate time difference, convert format of times, rank on new.dep.time within group, and filter
newDT <- miscon[tt, on = c("Outbound.airport", "weekday"), nomatch = 0][
  , new.dep.time := as.numeric(dep.time - arr.time)][
  , c("arr.time", "dep.time", "next.pos.dep") := .(format(arr.time, "%H:%M"), format(dep.time, "%H:%M"), format(next.pos.dep, "%H:%M"))][
  , new.dep.rank := rank(new.dep.time), by = c("Outbound.airport", "weekday")][
  new.dep.rank == 1, -c("new.dep.rank", "new.dep.time")]
#设置
库(数据表)
setDT(tt)
setDT(错误)
#使tt长格式拆分工作日

tt好的,这不太好,但你有一个相当复杂的问题,我不完全清楚这是否能提供你想要的-你需要在一个比你提供的小示例更大的数据集上检查它,以确保首先

# setup
library(data.table)
setDT(tt)
setDT(miscon)

# make tt long format splitting weekdays out
tt <- melt(tt[, paste("V", 1:7, sep = "") := tstrsplit(weekday, "")][, -"weekday"], measure.vars = paste("V", 1:7, sep = ""))[value != "."][, c("weekday", "value", "variable") := .(value, NULL, NULL)]

# join, calculate time difference, convert format of times, rank on new.dep.time within group, and filter
newDT <- miscon[tt, on = c("Outbound.airport", "weekday"), nomatch = 0][
  , new.dep.time := as.numeric(dep.time - arr.time)][
  , c("arr.time", "dep.time", "next.pos.dep") := .(format(arr.time, "%H:%M"), format(dep.time, "%H:%M"), format(next.pos.dep, "%H:%M"))][
  , new.dep.rank := rank(new.dep.time), by = c("Outbound.airport", "weekday")][
  new.dep.rank == 1, -c("new.dep.rank", "new.dep.time")]
#设置
库(数据表)
setDT(tt)
setDT(错误)
#使tt长格式拆分工作日

我想你可以这样做。首先,我将重新排列
Weekday
列,以便航班在每个工作日都有一行:

library(data.table)
library(dplyr)
library(tidyr)

tt <- tt %>% separate(weekday, into = as.character(1:7), sep = 1:6) %>% 
  gather(key="key", value="weekday", -c(start.date, end.date, Outbound.airport, dep.time)) %>%
  filter(weekday %in% 1:7) %>%
  select(-key)
检查航班日期是否在有效日期:

df = df[flight.date>=start.date & flight.date<=end.date]
现在,您可以按最小时间延迟(
timediff
)筛选行:


解决方案是将
dplyr
数据混合在一起。首先,我将重新排列
Weekday
列,以便航班在每个工作日都有一行:

library(data.table)
library(dplyr)
library(tidyr)

tt <- tt %>% separate(weekday, into = as.character(1:7), sep = 1:6) %>% 
  gather(key="key", value="weekday", -c(start.date, end.date, Outbound.airport, dep.time)) %>%
  filter(weekday %in% 1:7) %>%
  select(-key)
检查航班日期是否在有效日期:

df = df[flight.date>=start.date & flight.date<=end.date]
现在,您可以按最小时间延迟(
timediff
)筛选行:


解决方案是将
dplyr
数据混合在一起。table

我被
next.pos.dep
列搞糊涂了。这些信息相关吗?谢谢你的提问。这是最终的结果,但现在这无关紧要。原因是,下一次可能的出发时间需要比实际到达中转站晚25分钟(我刚刚编辑了这个问题,现在它说的是arr.time,而不是dep.time——为了更合理)。那么,下一次航班将是下一次可能起飞的最短时间。请提供代码,以使问题的最小重现性示例@rg255很抱歉,我现在在问题描述中提供了它。这
.3.5..
是否意味着航班将在一周的第三天和第五天起飞,星期三和星期五?我被
next.pos.dep
专栏搞糊涂了。这些信息相关吗?谢谢你的提问。这是最终的结果,但现在这无关紧要。原因是,下一次可能的出发时间需要比实际到达中转站晚25分钟(我刚刚编辑了这个问题,现在它说的是arr.time,而不是dep.time——为了更合理)。那么,下一次航班将是下一次可能起飞的最短时间。请提供代码,以使问题的最小重现性示例@rg255很抱歉,我现在在问题描述中提供了它。这
.3.5..
是否意味着航班将在一周的第三天和第五天起飞,星期三和星期五?这很好用,谢谢!!事实上,我在滚动连接方面做了一些类似的工作,但在工作日中遇到了困难,所以这一次很有帮助!然而,我仍然很难弄清楚如何确保新航班在正确的时间段内。“tt$start.date”和“tt$end.date”表示特定航班时间表的时间段,新的.flight.time需要在该时间段内。我试图使用<和>,将其添加到setkey()函数中,但没有成功。我编辑了答案,以便它检查航班日期是否在时刻表范围内。这非常有效,谢谢!!事实上,我在滚动连接方面做了一些类似的工作,但在工作日中遇到了困难,所以这一次很有帮助!然而,我仍然很难弄清楚如何确保新航班在正确的时间段内。“tt$start.date”和“tt$end.date”表示特定航班时间表的时间段,新的.flight.time需要在该时间段内。我试图使用<和>,将其添加到setkey()函数中,但没有成功。我编辑了答案,以便它检查航班日期是否在时刻表的范围内。
tt <- data.table(tt)
miscon <- data.table(miscon)
setkey(miscon, Outbound.airport, weekday)
setkey(tt, Outbound.airport, weekday)
df <- tt[miscon]
df = df[flight.date>=start.date & flight.date<=end.date]
df[,timediff:= dep.time-arr.time, by=.(weekday, Outbound.airport)]
df = df[ , .SD[which.min(timediff)],  by=.(weekday, Outbound.airport, flight.date, arr.time, next.pos.dep)]
setnames(df, "dep.time", "new.flight.time")

> df
   weekday Outbound.airport flight.date            arr.time        next.pos.dep start.date   end.date     new.flight.time   timediff
1:       7              KLU  2019-07-21 2020-04-27 07:33:00 2020-04-27 07:58:00 2019-03-25 2019-10-21 2020-04-27 12:20:00 17220 secs
2:       4              MXP  2019-08-05 2020-04-27 19:25:00 2020-04-27 19:36:00 2019-07-30 2019-08-26 2020-04-27 19:55:00  1800 secs
3:       3              OTP  2019-05-29 2020-04-27 18:49:00 2020-04-27 19:14:00 2019-05-29 2019-06-01 2020-04-27 20:34:00  6300 secs