在循环中使用 Mutate 和 Case_when 时出现问题
Issue when using Mutate and Case_when in a loop
我有一个数据框,其中包含那天 (lg) 赛艇的所有信息,我希望创建一个变量来告诉我赛艇参加的比赛。这场比赛的开始和结束时间是单独的df(种族信息)。我可以按比赛时间过滤,但每天的比赛数量是可变的,所以它可能需要一个循环。
一些数据
lg <- structure(list(Date = structure(c(18897, 18897, 18897, 18897,
18897, 18897, 18897, 18897, 18897, 18897), class = "Date"), Time = structure(c(1632725883,
1632725884, 1632725885, 1632725886, 1632725887, 1632725888, 1632725889,
1632725890, 1632725891, 1632725892), tzone = "", class = c("POSIXct",
"POSIXt")), Lat = c(43.2760531, 43.276059, 43.276065, 43.2760708,
43.2760766, 43.2760858, 43.276095, 43.2761, 43.276105, 43.2761095
), Lon = c(6.619109, 6.619136, 6.619163, 6.6191932, 6.6192235,
6.6192488, 6.619274, 6.6192988, 6.6193235, 6.6193532), Awa = c(-7.1,
-7.12, -7.15, -6.57, -6, -6.2, -6.4, -5.28, -4.15, 0.25), X = 1:10), row.names = c(NA,
-10L), class = "data.frame")
这是游艇上船数据
更多数据
RaceInfo <- structure(list(date = structure(c(18897, 18896), class = "Date"),
RaceStartTime = structure(c(1632738480, 1632751560), tzone = "", class = c("POSIXct",
"POSIXt")), RaceNum = c("1", "2"), RaceFinishTime = structure(c(1632751520,
1632753000), tzone = "", class = c("POSIXct", "POSIXt"))), row.names = c("event.2",
"1"), class = "data.frame")
在 RaceInfo df 中,它告诉我们每场比赛的开始和结束时间,如前所述,可能会有很多比赛,我需要根据给定的时间在 lg df 中分配一个新变量作为 lg$RaceNum在 RaceInfo df.
我的关闭尝试是这样的,但循环是我游戏中的一个弱点。
for (i in RaceInfo$RaceNum){
lg <- lg %>%
mutate(Racenum = case_when(
lg$Time >= (subset(RaceInfo$RaceStartTime, RaceInfo$RaceNum == i)) &
lg$Time <= (subset(RaceInfo$RaceFinishTime, RaceInfo$RaceNum == i)) ~ i))
}
但这只是returns循环中的最后一个数字
方法 mutate
和 case_when
实际上是在数据框中分配计算列,而不是专门用于子集数据框本身。
相反,请考虑 dplyr::filter
(similar to base::subset
) even dplyr::between
并收集您的迭代结果以构建数据框列表。然后,rbind
结果在最后。要按唯一值进行子集化,请参阅 by
df_list <- lapply(RaceInfo$RaceNum, function(i)
dplyr::filter(
lg,
dplyr::between(
Time,
RaceInfo$StartTime[RaceInfo$Racenum == i],
RaceInfo$RaceFinishTime[RaceInfo$Racenum == i]
)
)
)
final_df <- dplyr::bind_rows(df_list)
但如上所述,如果您的数据可以通过一小组不同的 RaceInfo
进行管理,请考虑使用过滤器进行交叉连接:
final_df <- dplyr::full_join(lg, RaceInfo, by = character()) %>%
filter(lg, between(
Time,
RaceInfo$StartTime[RaceInfo$Racenum == i],
RaceInfo$RaceFinishTime[RaceInfo$Racenum == i]
)
)
我有一个数据框,其中包含那天 (lg) 赛艇的所有信息,我希望创建一个变量来告诉我赛艇参加的比赛。这场比赛的开始和结束时间是单独的df(种族信息)。我可以按比赛时间过滤,但每天的比赛数量是可变的,所以它可能需要一个循环。
一些数据
lg <- structure(list(Date = structure(c(18897, 18897, 18897, 18897,
18897, 18897, 18897, 18897, 18897, 18897), class = "Date"), Time = structure(c(1632725883,
1632725884, 1632725885, 1632725886, 1632725887, 1632725888, 1632725889,
1632725890, 1632725891, 1632725892), tzone = "", class = c("POSIXct",
"POSIXt")), Lat = c(43.2760531, 43.276059, 43.276065, 43.2760708,
43.2760766, 43.2760858, 43.276095, 43.2761, 43.276105, 43.2761095
), Lon = c(6.619109, 6.619136, 6.619163, 6.6191932, 6.6192235,
6.6192488, 6.619274, 6.6192988, 6.6193235, 6.6193532), Awa = c(-7.1,
-7.12, -7.15, -6.57, -6, -6.2, -6.4, -5.28, -4.15, 0.25), X = 1:10), row.names = c(NA,
-10L), class = "data.frame")
这是游艇上船数据
更多数据
RaceInfo <- structure(list(date = structure(c(18897, 18896), class = "Date"),
RaceStartTime = structure(c(1632738480, 1632751560), tzone = "", class = c("POSIXct",
"POSIXt")), RaceNum = c("1", "2"), RaceFinishTime = structure(c(1632751520,
1632753000), tzone = "", class = c("POSIXct", "POSIXt"))), row.names = c("event.2",
"1"), class = "data.frame")
在 RaceInfo df 中,它告诉我们每场比赛的开始和结束时间,如前所述,可能会有很多比赛,我需要根据给定的时间在 lg df 中分配一个新变量作为 lg$RaceNum在 RaceInfo df.
我的关闭尝试是这样的,但循环是我游戏中的一个弱点。
for (i in RaceInfo$RaceNum){
lg <- lg %>%
mutate(Racenum = case_when(
lg$Time >= (subset(RaceInfo$RaceStartTime, RaceInfo$RaceNum == i)) &
lg$Time <= (subset(RaceInfo$RaceFinishTime, RaceInfo$RaceNum == i)) ~ i))
}
但这只是returns循环中的最后一个数字
方法 mutate
和 case_when
实际上是在数据框中分配计算列,而不是专门用于子集数据框本身。
相反,请考虑 dplyr::filter
(similar to base::subset
) even dplyr::between
并收集您的迭代结果以构建数据框列表。然后,rbind
结果在最后。要按唯一值进行子集化,请参阅 by
df_list <- lapply(RaceInfo$RaceNum, function(i)
dplyr::filter(
lg,
dplyr::between(
Time,
RaceInfo$StartTime[RaceInfo$Racenum == i],
RaceInfo$RaceFinishTime[RaceInfo$Racenum == i]
)
)
)
final_df <- dplyr::bind_rows(df_list)
但如上所述,如果您的数据可以通过一小组不同的 RaceInfo
进行管理,请考虑使用过滤器进行交叉连接:
final_df <- dplyr::full_join(lg, RaceInfo, by = character()) %>%
filter(lg, between(
Time,
RaceInfo$StartTime[RaceInfo$Racenum == i],
RaceInfo$RaceFinishTime[RaceInfo$Racenum == i]
)
)