【问题标题】:How to get the name of each element of a list using lapply()?如何使用 lapply() 获取列表中每个元素的名称?
【发布时间】:2015-09-10 15:20:15
【问题描述】:

想象一下我有以下列表

> test <- list("a" = 1, "b" = 2)

列表的每个元素都有一个名称:

> names(test)

现在,我想使用lapply() 提取该名称,因为我想在一个将使用 lapply 调用的新函数中使用它。我只是不知道如何提取每个元素的名称。

我尝试过使用deparse()substitute(),但结果很奇怪:

> lapply(test, function(x) {deparse(substitute(x))})
$a
[1] "X[[i]]"

$b
[1] "X[[i]]"

有人知道吗?

精度:

我想做这样的事情: 我有一个类似于 test 的列表:

> test <- list("a" = matrix(1, ncol = 3), "b" = matrix(2, ncol = 3))

我想对该列表应用一个函数来转换每个元素内的数据并为每一列指定一个特定的名称:

make_df <- function(x) {
  output <- data.frame(x)
  names(output) <- c("items", "type", NAME_OF_X)
  return(output)
}
lapply(test, make_df)

预期的输出是:

> test
$a
     [,1] [,2] [,3]
[1,]    1    1    1
attr(,"names")
[1] "index" "type"  "a"    

$b
     [,1] [,2] [,3]
[1,]    2    2    2
attr(,"names")
[1] "index" "type"  "b"    

我不知道如何获取元素的名称来为我的第三列命名。

【问题讨论】:

  • 尝试lapply(names(test), function(x) test[[x]]) 循环使用names,您可以选择获取值和键
  • lapply(seq_along(test), function(i) names(test[i]))
  • 好的,第二个有效,但我想要一些适用于列表的东西,而不是seq_along()
  • @PAC 我展示了获取值的方法,但如果您只需要密钥 lapply(names(test), function(x) x)
  • 您想要获取列表元素的名称,而链接看起来与您想要的内容重复

标签: r lapply


【解决方案1】:

这是使用purrr 的解决方案。它似乎比 aaronwolden 的解决方案运行得更快,但比 akrun 的解决方案慢(如果这很重要的话):

library(purrr)
map2(test, names(test), function(vec, name) {
    names(vec) <- c("index", "type", name)
    return(vec)
})

$a
     [,1] [,2] [,3]
[1,]    1    1    1
attr(,"names")
[1] "index" "type"  "a"    

$b
     [,1] [,2] [,3]
[1,]    2    2    2
attr(,"names")
[1] "index" "type"  "b"    

【讨论】:

    【解决方案2】:

    假设您希望 test 的两个元素都包含一个 3 列矩阵,您可以使用 mapply() 并分别提供列表和列表名称:

      test <- list("a" = matrix(1, ncol = 3), "b" = matrix(2, ncol = 3))
    
      make_df <- function(x, y) {
        output <- data.frame(x)
        names(output) <- c("items", "type", y)
        return(output)
      }
    
      mapply(make_df, x = test, y = names(test), SIMPLIFY = FALSE)
    

    产生:

    ## $a
    ##   items type a
    ## 1     1    1 1
    ##
    ## $b
    ##   items type b
    ## 1     2    2 2
    

    更新

    要实现您在更新问题中描述的预期输出:

    test.names <- lapply(names(test), function(x) c("index", "type", x))
    Map(setNames, test, test.names)
    

    产生:

    ## $a
    ##      [,1] [,2] [,3]
    ## [1,]    1    1    1
    ## attr(,"names")
    ## [1] "a"     "index" "type"  
    ## 
    ## $b
    ##      [,1] [,2] [,3]
    ## [1,]    2    2    2
    ## attr(,"names")
    ## [1] "b"     "index" "type"  
    

    【讨论】:

      【解决方案3】:

      基于预期的输出显示

        make_attr_names <- function(x){
         x1 <- test[[x]]
         attr(x1, 'names') <- c('items','type', x)
         x1}
      lapply(names(test), make_attr_names)  
       #[[1]]
       #    [,1] [,2] [,3]
       #[1,]    1    1    1
       #attr(,"names")
       #[1] "items" "type"  "a"    
      
       #[[2]]
       #    [,1] [,2] [,3]
       #[1,]    2    2    2
       #attr(,"names")
       #[1] "items" "type"  "b"  
      

      或根据描述

       make_df <- function(x){
             setNames(as.data.frame(test[[x]]), c('items', 'type', x))}
       lapply(names(test), make_df)
       #[[1]]
       # items type a
       #1     1    1 1
      
       #[[2]]
       #  items type b
       #1     2    2 2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-01
        • 2020-10-25
        • 2020-02-13
        • 1970-01-01
        相关资源
        最近更新 更多