是否有一种方法可以在我的lapply()函数中获得列表索引名?

n = names(mylist)
lapply(mylist, function(list.elem) { cat("What is the name of this list element?\n" })

我以前问过是否可以在lapply()返回的列表中保留索引名,但我仍然不知道是否有一种简单的方法来获取自定义函数中的每个元素名。我希望避免对名称本身调用lapply,我宁愿在函数参数中获得名称。


当前回答

假设我们想计算每个元素的长度。

mylist <- list(a=1:4,b=2:9,c=10:20)
mylist

$a
[1] 1 2 3 4

$b
[1] 2 3 4 5 6 7 8 9

$c
 [1] 10 11 12 13 14 15 16 17 18 19 20

如果目的仅仅是标记结果元素,那么lapply(mylist,length)或更低的值可以工作。

sapply(mylist,length,USE.NAMES=T)

 a  b  c 
 4  8 11 

如果目标是在函数内部使用标签,则mapply()通过遍历两个对象非常有用;列表元素和列表名称。

fun <- function(x,y) paste0(length(x),"_",y)
mapply(fun,mylist,names(mylist))

     a      b      c 
 "4_a"  "8_b" "11_c" 

其他回答

只需要把名字循环进去。

sapply(names(mylist), function(n) { 
    doSomething(mylist[[n]])
    cat(n, '\n')
}

同样的问题我已经遇到过很多次了…… 我开始用另一种方法…我不再使用lapply,而是开始使用mapply

n = names(mylist)
mapply(function(list.elem, names) { }, list.elem = mylist, names = n)

只需编写自己的自定义lapply函数

lapply2 <- function(X, FUN){
  if( length(formals(FUN)) == 1 ){
    # No index passed - use normal lapply
    R = lapply(X, FUN)
  }else{
    # Index passed
    R = lapply(seq_along(X), FUN=function(i){
      FUN(X[[i]], i)
    })
  }

  # Set names
  names(R) = names(X)
  return(R)
}

然后像这样使用:

lapply2(letters, function(x, i) paste(x, i))

您可以尝试从purrr包中使用imap()。

从文档中可以看到:

Imap (x,…)是map2(x, names(x),…)的简写,如果x有名称,则Imap (x, seq_along(x),…)

所以,你可以这样使用它:

library(purrr)
myList <- list(a=11,b=12,c=13) 
imap(myList, function(x, y) paste(x, y))

这将给你以下结果:

$a
[1] "11 a"

$b
[1] "12 b"

$c
[1] "13 c"

我的答案与Tommy和caracals的方向相同,但避免了将列表保存为额外对象。

lapply(seq(3), function(i, y=list(a=14,b=15,c=16)) { paste(names(y)[[i]], y[[i]]) })

结果:

[[1]]
[1] "a 14"

[[2]]
[1] "b 15"

[[3]]
[1] "c 16"

这将列表作为FUN的命名参数(而不是lapply)。Lapply只需要遍历列表的元素(在更改列表长度时,要注意将第一个参数更改为Lapply)。

注意:将列表直接作为附加参数提供给lapply也可以:

lapply(seq(3), function(i, y) { paste(names(y)[[i]], y[[i]]) }, y=list(a=14,b=15,c=16))