How to Conditionally Add a Named Element to a List in Base R
When constructing lists in R, a common requirement is to include a specific named element only if a condition evaluates to TRUE. Often, developers attempt something intuitive like this:
myfun <- function(z) {
list(x = 1, y = 2, z = if (z) 3)
}
While this works well when z = TRUE, passing z = FALSE leaves behind a lingering element with a value of NULL ($z: NULL), keeping the list length at 3 instead of the desired 2. In base R, how can you conditionally include a named element cleanly without relying on cumbersome temporary variable assignments?
The Best Base R Solution: Using c() with if
The cleanest, most idiomatic base R solution takes advantage of how c() handles NULL. When concatenating lists, c() automatically drops NULL values. If the condition is false, returning NULL causes the extra element to disappear completely without leaving an empty slot.
myfun <- function(z) {
c(list(x = 1, y = 2), if (z) list(z = 3))
}
How It Works:
- When
z = TRUE: The expressionif (z) list(z = 3)evaluates tolist(z = 3). Concatenatinglist(x = 1, y = 2)andlist(z = 3)results in a combined list of length 3:list(x = 1, y = 2, z = 3). - When
z = FALSE: Anifstatement without an explicitelsebranch returnsNULL. Becausec(list(...), NULL)ignoresNULL, the result is cleanly retained as a list of length 2:list(x = 1, y = 2).
myfun(TRUE)
#> $x
#> [1] 1
#>
#> $y
#> [1] 2
#>
#> $z
#> [1] 3
myfun(FALSE)
#> $x
#> [1] 1
#>
#> $y
#> [1] 2
Alternative Approach: In-Place Filtering with Filter()
If you prefer declaring all elements inside a single list() call and cleaning up afterward, you can wrap the list in Filter(Negate(is.null), ...):
myfun <- function(z) {
Filter(Negate(is.null), list(x = 1, y = 2, z = if (z) 3))
}
Caveat: Be cautious with this approach if your list could legitimately contain intended NULL values for other keys, as Filter(Negate(is.null), ...) will remove every NULL element across the entire list.
Splicing Multiple Conditional Elements
This c() pattern also scales elegantly when you need to conditionally append multiple values or evaluate multiple independent conditions:
make_config <- function(include_meta = FALSE, include_weights = FALSE) {
c(
list(id = 101, status = "active"),
if (include_meta) list(created_at = Sys.Date(), author = "admin"),
if (include_weights) list(weights = c(0.2, 0.8))
)
}
Summary
To add elements conditionally without creating verbose temporary variables or polluting the list with NULL keys, use c(list(...), if (cond) list(...)). It adheres strictly to base R, keeps code readable, and is ideal for lightweight patches in core packages.