I have a multi-level list l
with an arbitrary number of levels and entries. To give a simple example:
l <- list(a = 1,
b = list(x = 2, y = 3),
c = list(dog = 5, cat = list(fish = 3, mouse = 10))
)
In my package, the user passes an "address" which specifies an object in this list. The address is passed as a string, of the form:
address = "$c$cat$fish"
This excludes the name of the list itself.
I have written a function which checks whether the address is "valid", in the sense that I want to check whether an object exists at the specified address. The main substance of the function is as follows:
# this is the call to evaluate, as a string
expr_str <- paste0("address_value <- l", address)
# evaluate the call
eval(str2lang(expr_str))
if(is.null(address_value)){
warning("Address is NULL or not found in list")
}
Now, this works (although there is probably a more elegant way to do it). But the problem is that I get a NOTE in the CMD check because the address_value
doesn't have a visible binding, because it is created inside eval()
.
I want to get rid of the note but I'm not sure how to retrieve whatever is (or isn't) at address
without using eval()
.
Can anyone help with this problem?
CodePudding user response:
Have you considered using purrr::pluck
? I think it matches your requirements:
l %>% pluck('c', 'cat', 'fish')
[1] 3
CodePudding user response:
The assignment to address_value
can be outside of the eval
, which avoids the undeclared variable nag in the CMD check.
check_address <- function(address) {
expr_str <- paste0("l", address)
# evaluate the call
address_value <- eval(str2lang(expr_str))
if(is.null(address_value)){
warning("Address is NULL or not found in list")
}
address_value
}
Which results in:
check_address("$c$cat$fish")
#> [1] 3
check_address("$c$cat$banana")
#> NULL
#> Warning message:
#> In check_address("$c$cat$banana") : Address is NULL or not found in list