我喜欢 dplyr 的“progress_estimated”功能,但我不知道如何让进度条在 dplyr 链内工作。我在此处放置了一个可重现的示例,其中包含代码。
我有一个相当大的 data.frame,如下所示:
cdatetime latitude longitude
1 2013-01-11 06:40:00 CST 49.74697 -93.30951
2 2013-01-12 15:55:00 CST 49.74697 -93.30951
3 2013-01-07 20:30:00 CST 49.74697 -93.30951
我想使用库计算每个日期的日出时间
library(dplyr)
library(StreamMetabolism)
我可以让 dplyr 的进度估计栏在循环内工作,例如:
丑陋的循环(有效)
p <- progress_estimated(nrow(test))
for (i in 1:nrow(test)){
p$tick()$print()
datetime = as.POSIXct(substr(test$cdatetime[i], 1, 20), tz = "CST6CDT")
test$sunrise[i] <- sunrise.set(test$latitude[i], test$longitude[i], datetime, "CST6CDT", num.days = 1)[1,1]
}
但是我如何将它嵌套在我的函数中,这样我就可以避免使用循环?
更喜欢使用:
SunriseSet <- function(dataframe, timezone){
dataframe %>%
rowwise() %>%
mutate(# calculate the date-time using the correct timezone
datetime = as.POSIXct(substr(cdatetime, 1, 20), tz = timezone),
# Get the time of sunrise and sunset on this day, at the county midpoint
sunrise = sunrise.set(latitude, longitude, datetime, timezone, num.days = 1)[1,1])
}
这里如何获得进度条?
test2 <- SunriseSet(test, "CST6CDT")
以下是一些示例数据:
test <- data.frame(cdatetime = rep("2013-01-11 06:40:00", 300),
latitude = seq(49.74697, 50.04695, 0.001),
longitude = seq(-93.30951, -93.27960, 0.0001))
与其使用
rowwise()
,不如尝试将 map*
中的 purrr
函数与 progress_estimated()
配对。 这个答案遵循 https://rud.is/b/2017/03/27/all-in-on-r%E2%81%B4-progress-bars-on-first-post/. 的方法
首先,将您的函数包装在另一个更新进度条的函数中:
SunriseSet <- function(lat, long, date, timezone, num.days, .pb = NULL) {
if (.pb$i < .pb$n) .pb$tick()$print()
sunrise.set(lat, long, date, timezone, num.days)
}
然后,使用
pmap
或 pmap_df
迭代输入(将输出绑定到数据帧中):
library(purrr)
pb <- progress_estimated(nrow(test), 0)
test2 <- test %>%
mutate(
sunrise = pmap_df(
list(
lat = latitude,
long = longitude,
date = as.character(cdatetime)
),
SunriseSet,
timezone = "CST6CDT", num.days = 1, .pb = pb
)$sunrise
)
这是一个在 rowwise() 中使用 cli::cli_progress_bar 的解决方案。 .env 是一个 dplyr 变量,它具有当前环境(在 rowwise 内),您需要将其父级传递给 cli_progress_update。
x <- tibble::tribble(
~a,
1,
2,
3,
4,
5,
6,
7
)
cli::cli_progress_bar("Some progress", total = 7)
y <- x |>
dplyr::rowwise() |>
dplyr::mutate(b = (function(x){
Sys.sleep(50/100)
cli::cli_progress_update(.envir =parent.env(.env))
x
})(a))
我不太喜欢我的解决方案,但它有效。
print_tick_function <- function(x, p) {
p$tick()$print()
data.frame(x)
}
SunriseSet <- function(dataframe, timezone){
p <- progress_estimated(nrow(dataframe))
dataframe %>%
rowwise() %>%
do(print_tick_function(.,p)) %>%
mutate(
datetime = as.POSIXct(substr(cdatetime, 1, 20), tz = timezone),
sunrise = sunrise.set(latitude, longitude, datetime, timezone, num.days = 1)[1,1]
)
}
test2 <- SunriseSet(test, "CST6CDT")