【问题标题】:R - Subsetting list by paramaters of nested listR - 嵌套列表参数的子集列表
【发布时间】:2021-08-02 07:17:58
【问题描述】:

我有一个包含嵌套列表的列表 list_tot。

我想子集或创建一个新列表,根据指定的参数选择特定子集,详细信息如下:

List_1 <- list(a = matrix(5,2), b = matrix(5,7), c = matrix(5,9), d = matrix(5,3))
List_2 <- list(a = matrix(7,3), b = matrix(7,7), c = matrix(7,1), d = matrix(7,9))
List_3 <- list(a = matrix(5,2), b = matrix(5,7), c = matrix(5,9), d = matrix(5,3))
List_4 <- list(a = matrix(5,2), b = matrix(5,7), c = matrix(5,9), d = matrix(5,3))
List_5 <- list(a = matrix(5,2), b = matrix(5,7), c = matrix(5,9), d = matrix(5,3))

List_tot <- list(List_1, List_2, List_3, List_4, List_5)

上面写着:

[[1]]

[[1]]$a
     [,1]
[1,]    5
[2,]    5

[[1]]$b
     [,1]
[1,]    5
[2,]    5
[3,]    5
[4,]    5
[5,]    5
[6,]    5
[7,]    5

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

[[1]]$d
     [,1]
[1,]    5
[2,]    5
[3,]    5


[[2]]
[[2]]$a
     [,1]
[1,]    7
[2,]    7
[3,]    7

[[2]]$b
     [,1]
[1,]    7
[2,]    7
[3,]    7
[4,]    7
[5,]    7
[6,]    7
[7,]    7

[[2]]$c
     [,1]
[1,]    7
...etc

我要选择:

  1. 对于每个嵌套列表,仅选择列表/矩阵 a、c 和 d。
  2. 为每个嵌套列表选择两个具有最高行数的列表/矩阵。

所以New_List_tot 的输出为:

上面写着:

[[1]]

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

[[1]]$d
     [,1]
[1,]    5
[2,]    5
[3,]    5
etc...

任何帮助都会有所帮助。我所有的尝试,尝试使用 plyer 和 dplyr,但没有成功并且非常卡住。

【问题讨论】:

    标签: r list dplyr plyr


    【解决方案1】:

    我们可以使用base R 来执行此操作。不需要任何包裹

    lapply(List_tot, `[`, c("a", "c", "d"))
    

    或使用匿名函数

    lapply(List_tot, function(x) x[c("a", "c", "d")])
    

    如果我们需要前 2 个,order 行数(lengths 工作因为这些是单列 matrix,所以行数等于元素总数,得到 head行数的有序向量的names,并使用它来提取内部列表元素

    lapply(List_tot, function(x) {
          x1 <- x[c("a", "c", "d")]
          v1 <- lengths(x1)
          x1[head(names(v1)[order(-v1)], 2)]
        })
    

    【讨论】:

    • 如果这些不是单列,nrow() 会起作用吗?
    • @jackkelly 然后,我们需要sapply/lapply 的第二个循环,即v1 &lt;- sapply(x1, nrow)
    【解决方案2】:

    更新

    第二个目标,你可以试试

    lapply(
      List_tot,
      function(lst) {
        head(lst[c("a", "c", "d")][order(-sapply(lst[c("a", "c", "d")], nrow))], 2)
      }
    )
    

    给了

    [[1]]
    [[1]]$c
          [,1]
     [1,]    5
     [2,]    5
     [3,]    5
     [4,]    5
     [5,]    5
     [6,]    5
     [7,]    5
     [8,]    5
     [9,]    5
    
    [[1]]$d
         [,1]
    [1,]    5
    [2,]    5
    [3,]    5
    
    
    [[2]]
    [[2]]$d
          [,1]
     [1,]    7
     [2,]    7
     [3,]    7
     [4,]    7
     [5,]    7
     [6,]    7
     [7,]    7
     [8,]    7
     [9,]    7
    
    [[2]]$a
         [,1]
    [1,]    7
    [2,]    7
    [3,]    7
    
    
    [[3]]
    [[3]]$c
          [,1]
     [1,]    5
     [2,]    5
     [3,]    5
     [4,]    5
     [5,]    5
     [6,]    5
     [7,]    5
     [8,]    5
     [9,]    5
    
    [[3]]$d
         [,1]
    [1,]    5
    [2,]    5
    [3,]    5
    
    
    [[4]]
    [[4]]$c
          [,1]
     [1,]    5
     [2,]    5
     [3,]    5
     [4,]    5
     [5,]    5
     [6,]    5
     [7,]    5
     [8,]    5
     [9,]    5
    
    [[4]]$d
         [,1]
    [1,]    5
    [2,]    5
    [3,]    5
    
    
    [[5]]
    [[5]]$c
          [,1]
     [1,]    5
     [2,]    5
     [3,]    5
     [4,]    5
     [5,]    5
     [6,]    5
     [7,]    5
     [8,]    5
     [9,]    5
    
    [[5]]$d
         [,1]
    [1,]    5
    [2,]    5
    [3,]    5
    

    • 对于您的第一个目标“对于每个嵌套列表,仅选择列表/矩阵 a、c 和 d。”
    lapply(List_tot, `[`, c("a", "c", "d"))
    
    • 对于您的第二个目标,“为每个嵌套列表选择行数最多的列表/矩阵。”
    Map(`[`, List_tot, max.col(t(sapply(List_tot, lengths))))
    

    【讨论】:

    • @akrun 感谢您的反馈,您能解释一下吗?
    • 我的意思是(可能是我错了)。是否必须仅对选定的列表元素(即“a”、“c”、“d”)执行此操作,并返回每个外部 lis 的最大行数
    • @akrun Okey,我明白你的意思。我认为这是两个不同的目标......
    • 感谢您的信息,对于第二个目标,我试图获得行数最多的前 2 个列表。我刚刚编辑了 OP。
    【解决方案3】:

    @akrun 对第 1 步有一个明确的答案,即按列过滤。对于第 2 步,您可以尝试按行数过滤

    library(magrittr)
    List_colfilter <- lapply(List_tot, function(i)i[c("a","c","d")])
    
    longestlist <- function(l){
      maxr <- lapply(l,nrow) %>% unlist %>% max
      l2 <- lapply(l, function(x) if(nrow(x)==maxr) x else NA)
      for (n in names(l)){
        if (is.na(l2[n])){
          l2[n] <- NULL
        }
      }
      return(l2)
    }
    List_longfilter <- lapply(List_colfilter, longestlist)
    

    【讨论】:

      【解决方案4】:

      在基础 R 中你可以这样做:

      lapply(List_tot, 
         function(x) (y<-x[c("a", "c", "d")])[order(sapply(y, nrow), decreasing  = TRUE)[1:2]])
      
      [[1]]
      [[1]]$c
            [,1]
       [1,]    5
       [2,]    5
       [3,]    5
       [4,]    5
       [5,]    5
       [6,]    5
       [7,]    5
       [8,]    5
       [9,]    5
      
      [[1]]$d
           [,1]
      [1,]    5
      [2,]    5
      [3,]    5
       etc
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-21
        • 2020-11-24
        • 1970-01-01
        • 2020-07-18
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多