Home > Net >  Check if object exists in multi-level list at specified path
Check if object exists in multi-level list at specified path

Time:06-01

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
  • Related