Utility functions

Intro

I’ve been working on an R package, ggloop, for the past month, and with every function I write I am realizing the need for utility functions.  These are functions which do one thing but do it very well.  My latest utility function, list.pos(), retrieves the position of a character string within a list.

Internals

list.pos() has two arguments:

  • name = a character vector, usually of length 1; can also be a vector with length > 1
  • lst = a list; every component (list element) must have a name

The function is not recursive and so only returns the position of the top level components. It will not seek out matches within lower level components if it is a nested list. Here is what the code looks like:

list.pos <- function(name, lst){
  matches <- sapply(name, function(x){
    matched <- which(names(lst) %in% x)
    if(length(matched) == 0) matched <- NA
    matched
  })
  return(matches)
}

As you can see, if there is a match then the function will return the position, and if there is no match it will return NA. It also uses the names in the character vector as name attributes in the results vector – which makes the task of subsetting less of a hassle.

Example

In the following example I am going to split the R internal object mtcars into a list and then use list.pos() to find the specified list name attributes.

gears <- split(mtcars, mtcars$gear)
list.pos(name = c("1", "2", "3"), lst = gears)
#>  1  2  3 
#> NA NA  1 

In the example above, I split mtcars along the gear column. Each numeric value in gear now acts as the name for the respective list. There are only three values for gear: 3, 4, and 5. So when searching for c("1", "2", "3"), the first two return NA while the third returns the position 1.

One more example

Though the function is not recursive, certainly you can use lapply() to do the recursion for you. In this example I will split gears into a nested list along the carb column. Then I will use list.pos() within an lapply() loop to look recursively for specific name attributes.

carbs <- lapply(gears, function(x) split(x, x$carb))
lapply(carbs, function(x) list.pos(c("6", "8"), x))
#> $`3`
#>  6  8 
#> NA NA 
#> 
#> $`4`
#>  6  8 
#> NA NA 
#> 
#> $`5`
#> 6 8 
#> 3 4

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s