14

In PHP you can access both the names and values of an array in a for loop with

foreach ( $array as $key => $value ) {

Is there anything comparable in R, when looping over named lists?

Jonas
  • 121,568
  • 97
  • 310
  • 388
naught101
  • 18,687
  • 19
  • 90
  • 138
  • Can you be a little more specific about whether you are looping over a list with a `for` loop or with something like `lapply` in R? Maybe a very basic example (in R code)? – joran Jun 20 '12 at 04:31
  • @joran: clarified questions. Yes, for-looping over lists. I can't use lapply in this specific instance. I have asked a related question here: http://stackoverflow.com/questions/11112842/r-how-to-store-multi-layer-data – naught101 Jun 20 '12 at 04:34
  • 1
    Ok; you only get the vanilla `for` loop syntax in R. Typically you'd refer to each piece (name+element) by subsetting either `names(myList)` or `myList` with your loop index `i`. – joran Jun 20 '12 at 04:38
  • @joran: yeah, ok, maybe that's the only answer. I just realised that for lists of lists (one example of this case) you CAN use multiple *apply functions, for example `result <- lapply( somelist, lapply, apply, 2, sum)` works with a list of lists of matrices. But it won't work if you have to apply a non-`*apply` function somewhere in the middle (eg. `lapply( somelist, as.data.frame, lapply, apply, 2, sum)` doesn't work). – naught101 Jun 20 '12 at 04:56

3 Answers3

19

Here is a simpler way to do this:

for (name in names(myList)) {
    print(name)
    print(myList[[name]])
}

Note: I did not write this code. I copied it from this page.

kenny
  • 303
  • 2
  • 5
9

Using some dummy data and a silly contrived example

ll <- list(A = 1:10, B = LETTERS[1:10], C = letters[1:10])

You can lapply() over the indices of the elements of ll:

out <- lapply(seq_along(ll),
           function(ind, list, names) {
               paste(names[ind], "=", paste(list[[ind]], collapse = ", "))
           }, list = ll, names = names(ll))

R> out
[[1]]
[1] "A = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10"

[[2]]
[1] "B = A, B, C, D, E, F, G, H, I, J"

[[3]]
[1] "C = a, b, c, d, e, f, g, h, i, j"

or for() loop over the list:

ll2 <- vector("list", length(ll))
nams <- names(ll)
for(i in seq_along(ll)) {
    ll2[[i]] <- paste(nams[i], "=", paste(ll[[i]], collapse = ", "))
}
ll2

R> ll2
[[1]]
[1] "A = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10"

[[2]]
[1] "B = A, B, C, D, E, F, G, H, I, J"

[[3]]
[1] "C = a, b, c, d, e, f, g, h, i, j"
Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
3

To get the names of a list you just use names(list).

ll <- list(A = 1:10, B = LETTERS[1:10], C = letters[1:10])
names(ll)
#[1] "A" "B" "C"

Most of the *apply functions will return values that are appropriately named if the the list was named to begin with.

sapply(ll, max)
#   A    B    C 
#"10"  "J"  "j" 
IRTFM
  • 258,963
  • 21
  • 364
  • 487