## Access lapply index names inside FUN

Unfortunately, `lapply`

only gives you the elements of the vector you pass it.

The usual work-around is to pass it the names or indices of the vector instead of the vector itself.

But note that you can always pass in extra arguments to the function, so the following works:

`x <- list(a=11,b=12,c=13) # Changed to list to address concerns in commments`

lapply(seq_along(x), function(y, n, i) { paste(n[[i]], y[[i]]) }, y=x, n=names(x))

Here I use `lapply`

over the indices of `x`

, but also pass in `x`

and the names of `x`

. As you can see, the order of the function arguments can be anything - `lapply`

will pass in the "element" (here the index) to the first argument *not* specified among the extra ones. In this case, I specify `y`

and `n`

, so there's only `i`

left...

Which produces the following:

`[[1]]`

[1] "a 11"

[[2]]

[1] "b 12"

[[3]]

[1] "c 13"

**UPDATE** Simpler example, same result:

`lapply(seq_along(x), function(i) paste(names(x)[[i]], x[[i]]))`

Here the function uses "global" variable `x`

and extracts the names in each call.

## R lapply statement with index

The function `mapply`

works like `lapply`

but allows you to supply multiple vectors or lists.

In your case you can create a second vector, the same length of the list, just counting up:

`mapply(myfunction, mylist, seq_along(mylist))`

Let's try it:

`myfunction<- function(values, index){ `

cat("Adding values (", index, "): ", values[1], "...", values[2], " = ", sum(values), "\n" )

invisible(values[1] + values[2])

}

mylist <- list(c(5, 4), c(3, 2), c(1, 3))

mapply(myfunction, mylist, seq_along(mylist))

Result:

`Adding values ( 1 ): 5 ... 4 = 9 `

Adding values ( 2 ): 3 ... 2 = 5

Adding values ( 3 ): 1 ... 3 = 4

#### Advanced user fun

Just for fun, a careful reading of the `?lapply`

manual page reveals that the following also works:

`myfunction<- function(values){`

print(sprintf("Adding values: %i",substitute(values)[[3]]))

return(values[1] + values[2])

}

lapply(mylist, myfunction)

Which suggests a general function adaptor could be created to supply index to your original function (or any other), modified to expect a second index argument:

`myfunction<- function(values,index){`

print(sprintf("Adding values: %i",index))

return(values[1] + values[2])

}

Now the adaptor

`lapply_index_adaptor=function(f)function(x,...)f(x,substitute(x)[[3]],...)`

and now the lapply call, with the adaptor:

`lapply(mylist, lapply_index_adaptor(myfunction))`

## Access and preserve list names in lapply function

I believe that `lapply`

by default keeps the names attribute of whatever you are iterating over. When you store the names of `myList`

in `n`

, that vector no longer has any "names". So if you add that back in via,

`names(n) <- names(myList)`

and the use `lapply`

as before, you should get the desired result.

**Edit**

My brains a bit foggy this morning. Here's another, perhaps more convenient, option:

`sapply(n,FUN = ...,simplify = FALSE,USE.NAMES = TRUE)`

I was groping about, confused that `lapply`

didn't have a `USE.NAMES`

argument, and then I actually looked at the code for `sapply`

and realized I was being silly, and this was probably a better way to go.

## How to access index number within lapply

We can use `Map`

on the sequence of the `list`

and `cbind`

`Map(cbind, a2, new = seq_along(a2))`

-output

`[[1]]`

value new

1 11.4 1

[[2]]

value new

1 12.8 2

[[3]]

value new

1 15.6 3

A similar approach with `imap`

`library(purrr)`

library(dplyr)

imap(a2, ~ .x %>%

mutate(new = .y))

Or if we need `lapply`

, loop over the sequence, extract the `list`

element with `[[`

and `transform`

or `cbind`

`lapply(seq_along(a2), function(i) cbind(a2[[i]], new = i))`

-output

`[[1]]`

value new

1 11.4 1

[[2]]

value new

1 12.8 2

[[3]]

value new

1 15.6 3

## R:How to get name of element in lapply function?

I renamed `list`

to `listy`

to remove the clash with the base function. This is a variation on Señor O's answer in essence:

`do.call(rbind, Map("[<-", listy, TRUE, "group", names(listy) ) )`

# x y group

#A.1 1 3 A

#A.2 2 4 A

#B.1 1 7 B

#B.2 2 8 B

This is also very similar to a previous question and answer here: r function/loop to add column and value to multiple dataframes

The inner `Map`

part gives this result:

`Map("[<-", listy, TRUE, "group", names(listy) )`

#$A

# x y group

#1 1 3 A

#2 2 4 A

#

#$B

# x y group

#1 1 7 B

#2 2 8 B

...which in long form, for explanation's sake, could be written like:

`Map(function(data, nms) {data[TRUE,"group"] <- nms; data;}, listy, names(listy) )`

As @flodel suggests, you could also use R's built in `transform`

function for updating dataframes, which may be simpler again:

`do.call(rbind, Map(transform, listy, group = names(listy)) )`

## Access names of list elements in a loop

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)}

## index number of nested lapply

Here are a couple of approaches

Using `mapply`

`mapply(function(y, z) {`

lapply(c("x", "y", "z"), function(x) {

print(paste(y, x))

print(z)

})

},

mylist,

seq_along(mylist))

Or only `lapply`

`lapply(seq_along(mylist), function(y) {`

lapply(c("x", "y", "z"), function(x) {

print(paste(mylist[y], x))

})

})

### Related Topics

How to Convert a Factor to Integer\Numeric Without Loss of Information

Transpose/Reshape Dataframe Without "Timevar" from Long to Wide Format

Duplicating Rows in R Merge Function

Extract Rows for the First Occurrence of a Variable in a Data Frame

Combing a Categorical Variable to Create a New Categorical Variable in R

How to Declare a Vector of Zeros in R

Error in Confusion Matrix:The Data and Reference Factors Must Have the Same Number of Levels

Removing Columns That Are All 0

Add Legend to Geom_Line() Graph in R

Minimum (Or Maximum) Value of Each Row Across Multiple Columns

Splitting a Large Data Frame into Smaller Segments

Pass a String as Variable Name in Dplyr::Filter

Rstudio Does Not Display Any Output in Console After Entering Code

Why Are These Numbers Not Equal

How Does the 'Prop.Table()' Function Work in R

Case Statement Equivalent in R

Generate Multiple Graphics from Within an R Function

Is There an R Function For Finding the Index of an Element in a Vector