[R] working with list

Jason Turner jasont at indigoindustrial.co.nz
Thu Feb 20 09:44:03 CET 2003


On Wed, Feb 19, 2003 at 06:46:28AM -0800, Hiroyuki Kawakatsu wrote:
> hi,
> 
> i have two questions:

I counted three ;-)

> (1) lookup: given a list of 'strings' in a list, i want to know the index
> of a given string in the list. if the string is not in the list, the index
> can be 0 or length()+1. for example, suppose i have
> names <- c("dog", "cat", "pig", "fish");
> then i want
> lookup(names, "cat") to return 2 and
> lookup(names, "ant") to return 0 (or 5)

That's not a list of strings; it's a character-type vector.  See below
for more.

For this, grep() is your friend.  To match a word exactly, you need to
put the pattern between a ^ and a $, all in quotes.  If you don't,
you'll get all partial matches too (which is also pretty useful
sometimes).

eg:

> names <- c("dog", "cat", "pig", "fish","catskills","cat stevens")
> grep("^cat$",names)
[1] 2
> grep("cat",names)
[1] 2 5 6

(I'm told that now works on all platforms - thanks for the regexes,
R-core!)

> (2) combining lists: when lists are combined, the higher level list
> structure appears to be lost. what i mean is, suppose i have two lists
> with the same structure
> a <- list(name="foo", year=1989, grade="A");
> b <- list(name="bar", year=2000, grade="B+");
> then when i combine the two lists into one
> ab <- c(a, b);
> length(ab) returns length(a)+length(b), not 2.

c() makes vectors.  list() makes lists.  Vectors:  each element is of
the *same* data type (numeric, character, Date/Time, factor,
logical,...).  This is why you lose the list-like character above;
you've "pushed" everything into a character vector.  This is a handy
way of throwing away exotic data classes, btw.

I think what you wanted to do was:

ab <- list(a, b)
length(ab)
ab


> given a list of lists, is there any way i can loop through each
> list and work with the named components in each list? 

lapply() is your friend, and can help with recursion too.

lapply(your.big.list,function(bar,...) {

  listfunc <- function(foo,...) {
     #magic thing you do to non-list elements;
     #you didn't specify, so I'm not sure what you want.
  }

  if(is.list(bar)) 
    lapply(bar,listfunc)
  else
    listfunc(bar,...)                 
}


This can make life easy, but think really hard about what you want the
functions to do, and what values you want them to return, and how
you're going to structure this.  Generalised list travels aren't
trivial, particularly the return trip.

Hope that helps

Jason
-- 
Indigo Industrial Controls Ltd.
64-21-343-545
jasont at indigoindustrial.co.nz




More information about the R-help mailing list