R 管道链错误处理中的 tryCatch() 或 exists()

dee*_*oeh 2 r try-catch dplyr magrittr

我目前遇到了一个问题,我试图从一些上游计算中创建一个值表。通常,我一直假设每次创建这些数据框时至少会有一个值为 1;但我遇到过一个并非如此的例子,最后得到了一个看起来像这样的表:

df <- data.frame(
  Experiment_Batch = c(rep("008_1", 83),
                       rep("008_6", 82),
                       rep("520_0", 2),
                       rep("944_10", 84),
                       rep("944_8", 85),
                       rep("944_9", 72)),
  Overall = rep(0, 408)
  ) 
Run Code Online (Sandbox Code Playgroud)

这导致了以下下游处理:

df %>% 
  dplyr::count(Experiment_Batch, Overall) %>%
  tidyr::spread(Overall, n, fill = 0) %>% 
  dplyr::select(Experiment_Batch, `1`)
Run Code Online (Sandbox Code Playgroud)

出错:Error in overscope_eval_next(overscope, expr) : object '1' not found

我试过使用tryCatch()and exists(),但我似乎无法让它们正常工作。理想情况下,这一切都可以使用管道运算符优雅地处理。我已经知道我可以创建一个对象并根据需要在我的工作流程中添加一些 if-else 语句,但我想知道是否有一种......“更有趣”的方法来处理这个问题,所以我不会不得不分手工作。

Psi*_*dom 5

如果您想在列不存在的情况下忽略选择,您可以使用选择辅助函数;这里matches("^1$")将尝试选择名称完全匹配的列1,因为数据框没有该列,它只是忽略选择作为matches返回integer(0)

library(tidyverse)
df %>% 
    count(Experiment_Batch, Overall) %>%
    spread(Overall, n, fill = 0) %>% 
    select(Experiment_Batch, matches("^1$"))

# A tibble: 6 x 1
#  Experiment_Batch
#*           <fctr>
#1            008_1
#2            008_6
#3            520_0
#4           944_10
#5            944_8
#6            944_9
Run Code Online (Sandbox Code Playgroud)

matchesinteger(0)当非列名匹配被忽略的模式时返回select

matches("^1$", vars = c("0", "experiment"))
# integer(0)

matches("^1$", vars = c("0", "experiment", "1"))
# [1] 3
Run Code Online (Sandbox Code Playgroud)

如果您需要自定义错误捕获:

library(tidyverse)
df %>% 
    count(Experiment_Batch, Overall) %>%
    spread(Overall, n, fill = 0) %>% 
    {
        tryCatch(
            select(., Experiment_Batch, `1`), 
            error=function(e) select(., Experiment_Batch)
        )
    }
    # replace the error with the customized function to handle the exception

# A tibble: 6 x 1
#  Experiment_Batch
#*           <fctr>
#1            008_1
#2            008_6
#3            520_0
#4           944_10
#5            944_8
6            944_9
Run Code Online (Sandbox Code Playgroud)