[R] passing (or obtaining) index or element name of list to FUN in lapply()

Prof Brian Ripley ripley at stats.ox.ac.uk
Wed Jun 13 09:37:31 CEST 2007


On Tue, 12 Jun 2007, Stephen Tucker wrote:

> Hello everyone,
>
> I wonder if there is a way to pass the index or name of a list to a
> user-specified function in lapply(). For instance, my desired effect is
> something like the output of
>
>> L <- list(jack=4098,sape=4139)
>> lapply(seq(along=L),function(i,x) if(i==1) "jack" else "sape",x=L)
> [[1]]
> [1] "jack"
>
> [[2]]
> [1] "sape"

as.list(names(L))

>> lapply(seq(along=L),function(i,x) if(names(x)[i]=="jack") 1 else 2,x=L)
> [[1]]
> [1] 1
>
> [[2]]
> [1] 2

as.list(seq_along(L))

lapply() can be faster than a for-loop, but usually not by much: its main 
advantage is clarity of code.

I think we need a real-life example to see what you are trying to do.

> But by passing L as the first argument of lapply(). I thought there was a
> tangentially-related post on this mailing list in the past but I don't recall
> that it was ever addressed directly (and I can't seem to find it now). The
> examples above are perfectly good alternatives especially if I wrap each of
> the lines in "names<-"() to return lists with appropriate names assigned, but

Try something like

L[] <- lapply(seq_along(L),function(i,x) if(i==1) "jack" else "sape",x=L)

> it feels like I am essentially writing a FOR-LOOP - though I was surprised to
> find that speed-wise, it doesn't seem to make much of a difference (unless I
> have not selected a rigorous test):
>
>> N <- 10000
>> y <- runif(N)
> ## looping through elements of y
>> system.time(lapply(y,
> +                    function(x) {
> +                      set.seed(222)
> +                      mean(rnorm(1e4,x,1))
> +                    }))
> [1] 21.00  0.17 21.29    NA    NA
> ## looping through indices
>> system.time(lapply(1:N,
> +                    function(x,y) {
> +                      set.seed(222)
> +                      mean(rnorm(1e4,y[x],1))
> +                      },y=y))
> [1] 21.09  0.14 21.26    NA    NA
>
> In Python, there are methods for Lists and Dictionaries called enumerate(),
> and iteritems(), respectively. Example applications:
>
> ## a list
> L = ['a','b','c']
> [x for x in enumerate(L)]
> ## returns index of list along with the list element
> [(0, 'a'), (1, 'b'), (2, 'c')]
>
> ## a dictionary
> D = {'jack': 4098, 'sape': 4139}
> [x for x in D.iteritems()]
> ## returns element key (name) along with element contents
> [('sape', 4139), ('jack', 4098)]
>
> And this is something of the effect I was looking for...
>
> Thanks to all,
>
> Stephen
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



More information about the R-help mailing list