I’ve always been annoyed by how subsetting missing elements by name had different behaviors for lists vs. vectors.
For named lists, subsetting with a non-existent name returns a NULL
.
list(a = 1)[["b"]]
#> NULL
For named vectors, it errors with [[
.
c(a = 1)[["b"]]
#> subscript out of bounds
The case of [
is interesting because it returns a NA
.
c(a = 1)["b"]
#> <NA>
#> NA
I get why, but it’s not so useful. It breaks nice equivalencies between lists and vectors.
elNamed()
to subset by nameThen I discovered elNamed()
from {methods}
. It’s a sister of el()
that subsets by name (vs. position):
el(c(a = 1), 1)
#> [1] 1
elNamed(c(a = 1), "a")
#> [1] 1
What’s kinda cool about elNamed()
is that it returns NULL
for unmatched names, for both lists and vectors.
elNamed(list(a = 1), "b")
#> NULL
elNamed(c(a = 1), "b")
#> NULL
And you can even turn it into an assertion!
elNamed(list(a = 1), "b", mustFind = TRUE)
#> 'b' is not one of the element names
elNamed(c(a = 1), "b", mustFind = TRUE)
#> 'b' is not one of the element names
?elNamed
says it’s for “compatibility with S+”!
I don’t actually use elNamed()
in practice, though.
But cool find nonetheless :)
This post was adapted from a Mastodon exchange: https://fosstodon.org/@yjunechoe/111383917758940010
sessionInfo()
sessionInfo()
#> R version 4.4.1 (2024-06-14 ucrt)
#> Platform: x86_64-w64-mingw32/x64
#> Running under: Windows 11 x64 (build 26100)
#>
#> Matrix products: default
#>
#>
#> locale:
#> [1] LC_COLLATE=English_United States.utf8
#> [2] LC_CTYPE=English_United States.utf8
#> [3] LC_MONETARY=English_United States.utf8
#> [4] LC_NUMERIC=C
#> [5] LC_TIME=English_United States.utf8
#>
#> time zone: America/New_York
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> loaded via a namespace (and not attached):
#> [1] compiler_4.4.1 litedown_0.7.1 tools_4.4.1 codetools_0.2-20
#> [5] xfun_0.52 commonmark_1.9.5