【发布时间】:2021-02-20 15:17:01
【问题描述】:
背景 我在 R 中使用嵌套循环从移动应用程序中排除用户的重叠会话数据。由于我无法共享数据,我正在使用 nycflights13 包中的 flights 数据框,我也设法在其中复制了问题。
目标:排除所有从同一目的地出发并在时间上重叠(同时在空中)的航班。在重叠航班中,始终选择航班号最高的航班(在原始数据中是有意义的)。
问题:我最终只有 12 次航班,而不是预期的数千次。除了痛苦的低效率,你能看出问题在哪里吗?
重现问题所需的软件包:tidyverse,[nycflights13][1]
我们的“解决方案”:
# data (flights from package nycflights13)
df_flights <- flights
df_flights2 <- df_flights %>%
drop_na() %>%
filter(carrier == "MQ") %>% # to decrease running time, just a piece of the data
mutate(
unique_n_day = as.factor(as.numeric(date(time_hour))), # creating unique number for a day to loop over
dest = as.factor(dest),
air_time = air_time*60) # converting to seconds
flight_list <- list()
## loop
for (i in levels(df_flights2$dest)){
df_dest <- df_flights2[df_flights2$dest == i,]
for (d in levels(df_dest$unique_n_day)){
df_day <- df_dest[df_dest$unique_n_day == d,]
for(n in 1:nrow(df_day)){
df <- df_day[df_day$time_hour >= df_day$time_hour[n] &
df_day$time_hour <= df_day$time_hour[n] + df_day$air_time[n],]
if (nrow(df) >= 1){
flight_list[[n]] <- df[which(df$flight==max(df$flight))[1],]
}else(d <- "I know it is silly") # max() complains when the df is empty-> if statement
}
}
}
# unlisting
fulldata_flight <- do.call("rbind", flight_list)
# dropping duplicated values
fulldata_flight_clean <- distinct(fulldata_flight)
编辑: 如果寻找返回重叠间隔的函数,那么我建议使用 data.table::foverlaps() 函数,因为下面的解决方案不能完美地捕捉所有内容。 [1]:https://github.com/hadley/nycflights13
【问题讨论】:
-
您在
unique_n_day行中使用lubridate::date吗? -
我对“排除所有从同一目的地出发并在时间上重叠的航班(同时在空中)中的措辞感到困惑。在重叠的航班中,始终选择一个具有最高的航班号(在原始数据中是有道理的)。”是否要包括除时间和目的地重叠且没有最高航班号的航班之外的所有航班?
-
如果航班 A 与航班 B 重叠,航班 B 与航班 C 重叠,但航班 C 不与航班 A 重叠,您会查看哪些航班号来选择最高的航班号?
-
我不确定你想要什么的具体细节,但我预计与 data.table 的非 equi 连接将比这种方法快 10-100 倍。
-
对于您的用例来说,这似乎忽略了在不同日期开始的重叠会话是否不重要?如果会议时间很短,我可以想象这可以忽略不计。
标签: r nested-loops