Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating list in R, when some of the list elements are not available

Tags:

r

I want to create a list based on some of the elements, even if the elements are not available.

> group_vars <- list(hhrace,hhethn,hhsize,hhinc,hhage,hhcnty,hhkids,hhgeo)

here hhrace and hhcnty do not exist, but I want to create a list without those elements.

> group_vars <- list(hhrace,hhethn,hhsize,hhinc,hhage,hhcnty,hhkids,hhgeo)
  Error: object 'hhrace' not found

Desired Output-

> group_vars
  hhethn,hhsize,hhinc,hhage,hhkids,hhgeo

without the hhrace and the hhcnty.

like image 400
sarath gk Avatar asked Oct 29 '25 11:10

sarath gk


2 Answers

You can store them in a list of expressions with rlang::exprs and only keep the ones which exist:

library(purrr)

# define variables in global environment
hhethn <- hhsize <- hhinc <- hhage <- hhkids <- hhgeo <- TRUE

group_vars <- rlang::exprs(hhrace, hhethn, hhsize, hhinc, hhage, hhcnty, hhkids, hhgeo) %>% 
  keep(~exists(as.character(.x))) %>% 
  set_names(as.character(.)) %>% 
  map(eval)

group_vars
#$hhethn
#[1] TRUE
#
#$hhsize
#[1] TRUE
#
#$hhinc
#[1] TRUE
#
#$hhage
#[1] TRUE
#
#$hhkids
#[1] TRUE
#
#$hhgeo
#[1] TRUE

For a more general case you can create a function:

safe_list <- function(...){
  rlang::enexprs(...) %>% 
    keep(~exists(as.character(.x))) %>%
    set_names(as.character(.)) %>% 
    map(eval)
}

group_vars <- safe_list(hhrace, hhethn, hhsize, hhinc, hhage, hhcnty, hhkids, hhgeo)
like image 177
dave-edison Avatar answered Nov 01 '25 01:11

dave-edison


I just want to pick up a solution suggested in the comments, which I believe is more useful than appreciated.

To set the stage, let's create the objects as DiceboyT has done:

hhethn <- hhsize <- hhinc <- hhage <- hhkids <- hhgeo <- TRUE

I am also creating a vector with the names of the existing objects:

objects <- c("hhrace","hhethn","hhsize","hhinc","hhage","hhcnty","hhkids","hhgeo")

Now, I may be wrong, but I have a hunch that all you need is the vector of objects that actually exist. The following would help with that:

objects[objects %in% ls()]
[1] "hhethn" "hhsize" "hhinc"  "hhage"  "hhkids" "hhgeo" 

However, if you truly want to list, the following would help as well, setting all missing elements to FALSE:

mget(objects, ifnotfound = FALSE)
$hhrace
[1] FALSE
$hhethn
[1] TRUE
$hhsize
[1] TRUE
$hhinc
[1] TRUE
$hhage
[1] TRUE
$hhcnty
[1] FALSE
$hhkids
[1] TRUE
$hhgeo
[1] TRUE

Now, to get a list of these except for the missing ones, we could also do the following:

tmpfun <- function(lst, nme) {
  tryCatch(
    lst[[nme]] <- get(nme)
    , error = function(e) {return(lst)}
  )
  return(lst)
}

Reduce(tmpfun, objects, init = list())
$hhethn
[1] TRUE
$hhsize
[1] TRUE
$hhinc
[1] TRUE
$hhage
[1] TRUE
$hhkids
[1] TRUE
$hhgeo
[1] TRUE

which gives you the above results except for the cases where the object does not exist.

like image 20
coffeinjunky Avatar answered Nov 01 '25 00:11

coffeinjunky