I am currently experiencing a hiccup where I am trying to create a table of values from some upstream calculations. Typically, I've been assuming that there would be at least one value of 1 each time these data frames are created; but I've encountered an example where this wasn't the case, and ended up with a table that looks like this:
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)
)
This has caused the following downstream processing:
df %>%
dplyr::count(Experiment_Batch, Overall) %>%
tidyr::spread(Overall, n, fill = 0) %>%
dplyr::select(Experiment_Batch, `1`)
to error out: Error in overscope_eval_next(overscope, expr) : object '1' not found
.
I've tried using tryCatch()
and exists()
, but I can't quite seem to get these to work properly. Ideally, this would all be handled elegantly using pipe operators. I already know I could create an object and add in a few if-else statements as necessary to my workflow, but I'm wondering if there's a... "more interesting" way to take care of this, so I wouldn't have to break up the work.
You can use select helper functions, if you want to ignore the selection if the column doesn't exist; Here matches("^1$")
will try to select the column whose name exactly matches 1
, since the data frame doesn't have the column, it simply ignores the selection as matches
returns 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
matches
returns integer(0)
when non of the column names matches the pattern which gets ignored in select
:
matches("^1$", vars = c("0", "experiment"))
# integer(0)
matches("^1$", vars = c("0", "experiment", "1"))
# [1] 3
If you need to customize the error catch:
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