如何捕获在管道内评估 ggplot 对象时发生的错误?
How can I catch errors that occur when ggplot objects are evaluated within a pipe?
我正在根据原始 Covid 案例数据制作每日 powerpoint 幻灯片,今天,我们没有案例!太棒了,除了它打破了我的报告:-(
我生成 ggplots,并使用 officer 将它们放在 powerpoint 幻灯片上。 ggplot 错误仅在幻灯片创建管道内由官员评估时出现。
我可以在上游捕获错误,但是在幻灯片生成之前就这样做可以使代码更好,因为幻灯片生成过程是多层次的,尽管有错误但能够继续生成工件会很好.
Reprex 如下:
注意,错误不会出现在 R 3.6 中,可能是由于 scale_x_discrete 评估标签的方式发生了变化,但它会仍然有一个通用的方式来优雅地失败
library( stringr )
library(ggplot2)
library(officer)
data = structure(list(LGA = character(0), Sex = character(0)), row.names = integer(0), class = c("tbl_df",
"tbl", "data.frame"))
plot = ggplot( data, aes( LGA, Sex ) ) +
geom_point() +
scale_x_discrete(labels = function(x) str_wrap(x, width = 15))
read_pptx() %>%
add_slide( ) %>%
ph_with( plot, location=ph_location_type() )
#> Warning in rep(yes, length.out = len): 'x' is NULL so the result will be NULL
#> Error in ans[ypos] <- rep(yes, length.out = len)[ypos]: replacement has length zero
由 reprex package (v0.3.0)
于 2021-01-19 创建
看来我应该可以使用 purrr::possibly 来捕获错误,但它需要一个函数:
Error: Can't convert a `gg/ggplot` object to function
注:去掉了第二个例子
会话信息如下:
> sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows Server x64 (build 14393)
Matrix products: default
locale:
[1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C
[5] LC_TIME=English_Australia.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] purrr_0.3.4 officer_0.3.15 ggplot2_3.3.3 stringr_1.4.0
[5] nvimcom_0.9-92.3
loaded via a namespace (and not attached):
[1] xml2_1.3.2 magrittr_2.0.1 tidyselect_1.1.0 munsell_0.5.0
[5] uuid_0.1-4 colorspace_1.4-1 R6_2.5.0 rlang_0.4.8
[9] dplyr_1.0.2 tools_4.0.3 grid_4.0.3 gtable_0.3.0
[13] withr_2.3.0 ellipsis_0.3.1 tibble_3.0.4 lifecycle_0.2.0
[17] crayon_1.3.4 zip_2.1.1 vctrs_0.3.4 glue_1.4.2
[21] stringi_1.5.3 compiler_4.0.3 pillar_1.4.6 generics_0.1.0
[25] scales_1.1.1 pkgconfig_2.0.3
>
我不能 100% 确定这是你的问题,因为我无法复制错误,但你可以尝试在 tryCatch()
中包装你的 ggplot 调用来处理错误:
tryCatch({
plot <- ggplot( data, aes( LGA, Sex ) ) +
geom_point() +
scale_x_discrete(labels = function(x) str_wrap(x, width = 15))
read_pptx() %>%
add_slide( ) %>%
ph_with( plot, location=ph_location_type() )
}, error = function(e) {
message(as.character(e)) # exclude this line to return NULL quietly
return(NULL)
}
)
read_pptx() %>%
add_slide( ) %>%
ph_with( plot, location=ph_location_type() )
如果我在将 geom_point()
更改为 geom_pointesa()
的 ggplot 调用中故意出错,您将得到以下结果:
Error in geom_pointesa(): could not find function "geom_pointesa"
NULL
请注意,在这种情况下,ggplot
调用 returns NULL
,同时打印一条错误消息以供审核。
sessionInfo()
下面:
R version 3.6.2 (2019-12-12)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] officer_0.3.16 ggplot2_3.2.1 stringr_1.4.0
loaded via a namespace (and not attached):
[1] Rcpp_1.0.3 xml2_1.2.2 magrittr_2.0.1 tidyselect_1.1.0 munsell_0.5.0 uuid_0.1-4 colorspace_1.4-1 R6_2.5.0 rlang_0.4.9
[10] dplyr_1.0.2 tools_3.6.2 grid_3.6.2 gtable_0.3.0 withr_2.3.0 ellipsis_0.3.1 lazyeval_0.2.2 tibble_2.1.3 lifecycle_0.2.0
[19] crayon_1.3.4 zip_2.1.1 purrr_0.3.3 vctrs_0.3.5 glue_1.4.2 stringi_1.4.4 compiler_3.6.2 pillar_1.4.7 generics_0.1.0
[28] scales_1.1.1 pkgconfig_2.0.3
错误发生在 ggplot_build()
构建地块时。通常你不会直接调用它,它是由显示对象的函数调用的,但你可以自己调用它。例如,
if (inherits(try(ggplot_build(plot)), "try-error"))
plot <- ggplot()
将用空白的情节替换糟糕的情节。
我正在根据原始 Covid 案例数据制作每日 powerpoint 幻灯片,今天,我们没有案例!太棒了,除了它打破了我的报告:-(
我生成 ggplots,并使用 officer 将它们放在 powerpoint 幻灯片上。 ggplot 错误仅在幻灯片创建管道内由官员评估时出现。
我可以在上游捕获错误,但是在幻灯片生成之前就这样做可以使代码更好,因为幻灯片生成过程是多层次的,尽管有错误但能够继续生成工件会很好.
Reprex 如下:
注意,错误不会出现在 R 3.6 中,可能是由于 scale_x_discrete 评估标签的方式发生了变化,但它会仍然有一个通用的方式来优雅地失败
library( stringr )
library(ggplot2)
library(officer)
data = structure(list(LGA = character(0), Sex = character(0)), row.names = integer(0), class = c("tbl_df",
"tbl", "data.frame"))
plot = ggplot( data, aes( LGA, Sex ) ) +
geom_point() +
scale_x_discrete(labels = function(x) str_wrap(x, width = 15))
read_pptx() %>%
add_slide( ) %>%
ph_with( plot, location=ph_location_type() )
#> Warning in rep(yes, length.out = len): 'x' is NULL so the result will be NULL
#> Error in ans[ypos] <- rep(yes, length.out = len)[ypos]: replacement has length zero
由 reprex package (v0.3.0)
于 2021-01-19 创建看来我应该可以使用 purrr::possibly 来捕获错误,但它需要一个函数:
Error: Can't convert a `gg/ggplot` object to function
注:去掉了第二个例子
会话信息如下:
> sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows Server x64 (build 14393)
Matrix products: default
locale:
[1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C
[5] LC_TIME=English_Australia.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] purrr_0.3.4 officer_0.3.15 ggplot2_3.3.3 stringr_1.4.0
[5] nvimcom_0.9-92.3
loaded via a namespace (and not attached):
[1] xml2_1.3.2 magrittr_2.0.1 tidyselect_1.1.0 munsell_0.5.0
[5] uuid_0.1-4 colorspace_1.4-1 R6_2.5.0 rlang_0.4.8
[9] dplyr_1.0.2 tools_4.0.3 grid_4.0.3 gtable_0.3.0
[13] withr_2.3.0 ellipsis_0.3.1 tibble_3.0.4 lifecycle_0.2.0
[17] crayon_1.3.4 zip_2.1.1 vctrs_0.3.4 glue_1.4.2
[21] stringi_1.5.3 compiler_4.0.3 pillar_1.4.6 generics_0.1.0
[25] scales_1.1.1 pkgconfig_2.0.3
>
我不能 100% 确定这是你的问题,因为我无法复制错误,但你可以尝试在 tryCatch()
中包装你的 ggplot 调用来处理错误:
tryCatch({
plot <- ggplot( data, aes( LGA, Sex ) ) +
geom_point() +
scale_x_discrete(labels = function(x) str_wrap(x, width = 15))
read_pptx() %>%
add_slide( ) %>%
ph_with( plot, location=ph_location_type() )
}, error = function(e) {
message(as.character(e)) # exclude this line to return NULL quietly
return(NULL)
}
)
read_pptx() %>%
add_slide( ) %>%
ph_with( plot, location=ph_location_type() )
如果我在将 geom_point()
更改为 geom_pointesa()
的 ggplot 调用中故意出错,您将得到以下结果:
Error in geom_pointesa(): could not find function "geom_pointesa"
NULL
请注意,在这种情况下,ggplot
调用 returns NULL
,同时打印一条错误消息以供审核。
sessionInfo()
下面:
R version 3.6.2 (2019-12-12)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] officer_0.3.16 ggplot2_3.2.1 stringr_1.4.0
loaded via a namespace (and not attached):
[1] Rcpp_1.0.3 xml2_1.2.2 magrittr_2.0.1 tidyselect_1.1.0 munsell_0.5.0 uuid_0.1-4 colorspace_1.4-1 R6_2.5.0 rlang_0.4.9
[10] dplyr_1.0.2 tools_3.6.2 grid_3.6.2 gtable_0.3.0 withr_2.3.0 ellipsis_0.3.1 lazyeval_0.2.2 tibble_2.1.3 lifecycle_0.2.0
[19] crayon_1.3.4 zip_2.1.1 purrr_0.3.3 vctrs_0.3.5 glue_1.4.2 stringi_1.4.4 compiler_3.6.2 pillar_1.4.7 generics_0.1.0
[28] scales_1.1.1 pkgconfig_2.0.3
错误发生在 ggplot_build()
构建地块时。通常你不会直接调用它,它是由显示对象的函数调用的,但你可以自己调用它。例如,
if (inherits(try(ggplot_build(plot)), "try-error"))
plot <- ggplot()
将用空白的情节替换糟糕的情节。