有没有办法将 seq() 和 grep() 向量化以与 dplyr 结合使用?
Is there a way to vectorize seq() and grep() to use on conjunction with dplyr?
很抱歉,如果这很明显,我对 R 没有太多经验。我有一个函数 contains_leap_year(date1, date2)
,我想将其作为条件传递给 dplyr::if_else()
。
我的 for 循环实现如下所示
contains_leap_year <- c()
for (i in 1:nrow(df)) {
if (df$date1[i] < 0 & !is.na(df$date2[i])) {
seq_str <- seq(df$date1[i], dat$date2[i], by = "day")
res <- (length(grep("-02-29", seq_str)) > 0)
}
else {
res <- FALSE
}
contains_leap_year <- append(contains_leap_year, res)
}
然后我会将此列附加到我的数据框,并执行类似
的操作
dplyr::mutate(
res = dplyr::if_else(contains_leap_year == TRUE, action1, action2)
)
但这相当慢。理想情况下,我想像这样 dplyr
一直工作
dplyr::mutate(
res = dplyr::if_else(length(grep("-02-29", seq(date1, date2, by = "day"))) > 0, action1, action2)
)
但是,这样做会引发'from' must be of length 1
错误,我认为这是因为date1
和date2
是向量,所以seq
无法构造序列。
如果这不可能,是否有比 for 循环更快的替代方法?
虽然不理想,但我已经(暂时)决定只循环遍历向量,但使用 furrr::future_map2
来这样做。我没有任何严格的基准测试,但在我的数据集上它比 purr::map2
快 2.5 倍左右,比 for 循环快 10 倍左右。
示例函数
contains_leap_day <- function(x, y) {
date_seqs <- format(seq(x, y, by = "day"))
res <- (length(stringr::str_which(date_seqs, "-02-29")) > 0)
return(res)
}
future::plan(multisession)
df %>%
dplyr::mutate(
has_leap_day = furrr::future_map2(year1, year2, contains_leap_day, .progress = TRUE)
)
很抱歉,如果这很明显,我对 R 没有太多经验。我有一个函数 contains_leap_year(date1, date2)
,我想将其作为条件传递给 dplyr::if_else()
。
我的 for 循环实现如下所示
contains_leap_year <- c()
for (i in 1:nrow(df)) {
if (df$date1[i] < 0 & !is.na(df$date2[i])) {
seq_str <- seq(df$date1[i], dat$date2[i], by = "day")
res <- (length(grep("-02-29", seq_str)) > 0)
}
else {
res <- FALSE
}
contains_leap_year <- append(contains_leap_year, res)
}
然后我会将此列附加到我的数据框,并执行类似
的操作dplyr::mutate(
res = dplyr::if_else(contains_leap_year == TRUE, action1, action2)
)
但这相当慢。理想情况下,我想像这样 dplyr
一直工作
dplyr::mutate(
res = dplyr::if_else(length(grep("-02-29", seq(date1, date2, by = "day"))) > 0, action1, action2)
)
但是,这样做会引发'from' must be of length 1
错误,我认为这是因为date1
和date2
是向量,所以seq
无法构造序列。
如果这不可能,是否有比 for 循环更快的替代方法?
虽然不理想,但我已经(暂时)决定只循环遍历向量,但使用 furrr::future_map2
来这样做。我没有任何严格的基准测试,但在我的数据集上它比 purr::map2
快 2.5 倍左右,比 for 循环快 10 倍左右。
示例函数
contains_leap_day <- function(x, y) {
date_seqs <- format(seq(x, y, by = "day"))
res <- (length(stringr::str_which(date_seqs, "-02-29")) > 0)
return(res)
}
future::plan(multisession)
df %>%
dplyr::mutate(
has_leap_day = furrr::future_map2(year1, year2, contains_leap_day, .progress = TRUE)
)