【问题标题】:How to extract elements and their indices from a list in R如何从R中的列表中提取元素及其索引
【发布时间】:2026-02-23 18:25:01
【问题描述】:

我想在 R 中提取列表元素及其索引,同时删除长度为 0 的项目。假设我在 R 中有以下列表:

l1 <- character(0)
l2 <- c("a","b")
l3 <- c("c","d","e")
list1 <- list(l1, l1, l2, l1, l3)

然后list1 返回以下内容:

[[1]]
character(0)
[[2]]
character(0)
[[3]]
[1] "a" "b"
[[4]]
character(0)
[[5]]
[1] "c" "d" "e"

我想以某种方式提取一个对象,该对象显示每个非空元素的索引/位置,以及该元素的内容。所以看起来像这样:

[[3]]
[1] "a" "b"
[[5]]
[1] "c" "d" "e"

我最接近的方法是删除空元素,但随后我丢失了剩余元素的原始索引/位置:

list2 <- list1[lapply(list1, length) > 0]
list2
[[1]]
[1] "a" "b"
[[2]]
[1] "c" "d" "e"

【问题讨论】:

  • setNames(list1[lengths(list1) &gt; 0], which(lengths(list1) &gt; 0))
  • 非常感谢!这是一个很好的简单命令,可以满足我的要求。

标签: r list extract


【解决方案1】:

keep,将保留与谓词匹配的元素。 negate(is_empty) 创建一个函数,如果向量不为空,则返回 TRUE

library("purrr")


names(list1) <- seq_along(list1)
keep(list1, negate(is_empty))
#> $`3`
#> [1] "a" "b"
#> 
#> $`5`
#> [1] "c" "d" "e"

【讨论】:

  • purrr::keep 在这里有点分散注意力。重要的部分只是names(list1) &lt;- seq_along(list1),即names(list1) &lt;- seq_along(list1); list1[lapply(list1, length) &gt; 0] 产生同样的东西。
【解决方案2】:

概述

保留索引需要我命名列表中的每个元素。此答案使用which() 设置我应用于list1 以保持非零长度元素的条件。

# load data
l1 <- character(0)
l2 <- c("a","b")
l3 <- c("c","d","e")
list1 <- list( l1, l1, l2, l1, l3)

# name each element in the list
names( list1 ) <- as.character( 1:length( list1 ) )

# create a condition that 
# keeps only non zero length elements
# from list1
non.zero.length.elements <-
  which( lapply( X = list1, FUN = length ) != 0 )

# apply the condition to list1
# to view the non zero length elements
list1[ non.zero.length.elements ]
# $`3`
# [1] "a" "b"
# 
# $`5`
# [1] "c" "d" "e"

# end of script #

【讨论】:

    【解决方案3】:

    我不确定“提取显示的对象”究竟是什么意思,但如果您只想打印,可以使用修改后的print

    我只是稍微编辑了print.listof(它不是递归的!将显示零长度子元素):

    print2 <- function (x, ...) 
    {
      nn <- names(x)
      ll <- length(x)
      if (length(nn) != ll) 
        nn <- paste0("[[", seq.int(ll),"]]")
      for (i in seq_len(ll)[lengths(x)>0]) {
        cat(nn[i], "\n")
        print(x[[i]], ...)
        cat("\n")
      }
      invisible(x)
    }
    
    print2(list1)
    
    [[3]] 
    [1] "a" "b"
    
    [[5]] 
    [1] "c" "d" "e"
    

    【讨论】:

      【解决方案4】:

      一个非常简单的解决方案是为列表中的元素提供名称,然后再次运行您的函数。有几种方法可以命名您的元素。

      l1 <- character(0)
      l2 <- c("a","b")
      l3 <- c("c","d","e")
      list1 <- list(e1=l1, e2=l1, e3=l2, e4=l1, e5=l3)
      list1
      names(list1)<-paste0("element",seq(length(list1)))
      list1[lapply(list1, length) > 0]
      

      【讨论】: