I need to parse a batch of spreadsheets that have the same data, but in five or six distinct formats. I can handle this when the processing steps are small:
Good question. An off-the-top-of-my-head answer is to write your function with argument parameters that can vary with the pattern. I can't tell without reproducible example, called a reprex whether you need to go further into a full-fledged parser, but that's another option.
Here are two ideas. First, I avoid branching with if() and try to write functions that handle the differences more generically. This function returns all non-Null elements of the list.
obj1 <- list(a = 'A', b = NULL)
obj2 <- list(a = NULL, b = 'B')
parser <- function(obj) {
NotNull <- sapply(obj, function(x) !is.null(x))
unlist(obj[NotNull])
}
parser(obj1)
#> a
#> "A"
parser(obj2)
#> b
#> "B"
Created on 2019-10-29 by the reprex package (v0.3.0.9000)
Another approach, about which I know just enough to be dangerous, is to use the S3 object system to write functions for different classes of objects and assign classes to your data according to the format. The book Advanced R explains how this works.
#Define a generic function
parser2 <- function(obj) {
UseMethod("parser2", obj)
}
#provide functions for different classes of objects
parser2.first <- function(obj) {
return(obj$a)
}
parser2.second <- function(obj) {
return(obj$b)
}
#Make objects and give them classes corresponding to the functions above
obj3 <- list(a = 'A', b = NULL)
class(obj3) <- "first"
obj4 <- list(a = NULL, b = 'B')
class(obj4) <- "second"
parser2(obj3)
#> [1] "A"
parser2(obj4)
#> [1] "B"
Created on 2019-10-29 by the reprex package (v0.3.0.9000)