1

I have a list with named elements like so:

lst <- list(a1 = 5:12, b4 = c(34,12,5), c3 = 23:45)

I can easily retrieve the element names like so:

names(lst)

In a function I can loop over the list elements, but how can I access the name of the element that is being accessed in the loop:

test <- function(lst) {
  for (l in lst) {
    cat("The name of the current list element is", ???, "\n")
    # Other processing of the list element
  }
}
Patrick
  • 29,357
  • 6
  • 62
  • 90
  • You can define the loop with `for (n in names(lst))` and use `n` in your call to `cat` and `lst[[n]]` to access the value of the corresponding element. Though, as @zx8754 remarks, it would be better to use the `apply` family to process the list. – Limey Jan 18 '22 at 11:25
  • 2
    When working with with lists, use `*apply` functions, e.g.: `lapply(names(lst), function(i) doStuff(i))` – zx8754 Jan 18 '22 at 11:26
  • 2
    `purrr` provides some convenience functions for these actions, similar to @zx8754 mention of `*apply*`. `purrr::imap(lst, ~ {cat("name is ", .y, "\n") ; .x + 1} )` – Donald Seinen Jan 18 '22 at 11:29

3 Answers3

4

Maybe this could help

for (l in seq_along(lst)) {
  cat("The name of the current list element is", names(lst[l]), "\n")
  # Other processing of the list element
}

which gives

The name of the current list element is a1 
The name of the current list element is b4
The name of the current list element is c3
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
1

In the purrr package, there are the functions imap() and iwalk(). They take a list and a function with two arguments and apply the function to every element of the list and its index/name. The difference is, that iwalk silently returns NULL and is executed only for side effects (helpful if you map over cat()) and imap() works similar to lapply() only it uses the functions second argument for the list's names.

library(purrr)
lst <- list(a1 = 5:12, b4 = c(34,12,5), c3 = 23:45)

imap(lst,\(x,y) cat("The name of the current list element is", y, "\n"))
#> The name of the current list element is a1 
#> The name of the current list element is b4 
#> The name of the current list element is c3
#> $a1
#> NULL
#> 
#> $b4
#> NULL
#> 
#> $c3
#> NULL

iwalk(lst,\(x,y) cat("The name of the current list element is", y, "\n"))
#> The name of the current list element is a1 
#> The name of the current list element is b4 
#> The name of the current list element is c3

Created on 2022-01-18 by the reprex package (v2.0.1)

shs
  • 3,683
  • 1
  • 6
  • 34
1

purrr's imap (and iwalk) are good functions if you want to access both data and the name of the list.

In base R, you may do this with any of the apply function which has been already mentioned in comments. Here's one using Map -

Map(function(x, y) sprintf('List name is %s and sum to %d', y, sum(x)), 
    lst, names(lst))

#$a1
#[1] "List name is a1 and sum to 68"

#$b4
#[1] "List name is b4 and sum to 51"

#$c3
#[1] "List name is c3 and sum to 782"
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213