【问题标题】:Naming elements of a nested list from their index in R根据 R 中的索引命名嵌套列表的元素
【发布时间】:2017-01-18 11:59:57
【问题描述】:

我得到了这个嵌套列表:

dico <- list(list(list(c("dim.", "dimension", "dimensions", "mesures"
), c("45 cm", "45", "45 CM", "0.45m")), list(c("tamano", "volumen", 
"dimension", "talla"), c("45 cm", "45", "0.45 M", "45 centimiento"
)), list(c("measures", "dimension", "measurement"), c("45 cm", 
"0.45 m", "100 inches", "100 pouces"))), list(list(c("poids", 
"poid", "poids net"), c("100 grammes", "100 gr", "100")), list(
    c("peso", "carga", "peso especifico"), c("100 gramos", "100g", 
    "100", "100 g")), list(c("weight", "net wieght", "weight (grammes)"
), c("100 grams", "100", "100 g"))), list(list(c("Batterie oui/non", 
"batterie", "présence batterie"), c("Oui", "batterie", "OUI"
)), list(c("bateria", "bateria si or no", "bateria disponible"
), c("si", "bateria furnindo", "1")), list(c("Battery available", 
"battery", "battery yes or no"), c("yes", "Y", "Battery given"
))))

[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1] "dim."       "dimension"  "dimensions" "mesures"   

[[1]][[1]][[2]]
[1] "45 cm" "45"    "45 CM" "0.45m"

我想要的是创建一个具有相同结构但不具有原始值的列表,我想要一种“索引”名称,例如:

[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1] "1|1|1|1"       "1|1|1|2"  "1|1|1|3" "1|1|1|4"   

[[1]][[1]][[2]]
[1] "1|1|2|1" "1|1|2|2"    "1|1|2|3" "1|1|2|4"

等等……

当然,通过不同的嵌套索引,元素的数量不是恒定的。有谁知道该怎么做?我听说过 rapply,但我做不到。

【问题讨论】:

    标签: r list nested


    【解决方案1】:

    试试这个带有 2 行正文的递归函数。它不假设一个固定的深度并且允许不平衡的列表。不使用任何包。

    它接受一个对象L 和一个级别。如果对象不是列表,那么我们有一个叶子,它返回它的级别。如果对象是一个列表,那么我们有一个节点,它遍历它的组件调用indexer,每个传递levi| 的串联作为第i 个组件的级别。

    indexer <- function(L, lev = character(0)) {
        if (!is.list(L)) paste0(lev, seq_along(L))
        else Map(indexer, L, paste0(lev, seq_along(L), "|"))
    }
    

    示例1使用问题中的dico

    > str( indexer(dico) )
    List of 3
     $ :List of 3
      ..$ :List of 2
      .. ..$ : chr [1:4] "1|1|1|1" "1|1|1|2" "1|1|1|3" "1|1|1|4"
      .. ..$ : chr [1:4] "1|1|2|1" "1|1|2|2" "1|1|2|3" "1|1|2|4"
      ..$ :List of 2
      .. ..$ : chr [1:4] "1|2|1|1" "1|2|1|2" "1|2|1|3" "1|2|1|4"
      .. ..$ : chr [1:4] "1|2|2|1" "1|2|2|2" "1|2|2|3" "1|2|2|4"
      ..$ :List of 2
      .. ..$ : chr [1:3] "1|3|1|1" "1|3|1|2" "1|3|1|3"
      .. ..$ : chr [1:4] "1|3|2|1" "1|3|2|2" "1|3|2|3" "1|3|2|4"
     $ :List of 3
      ..$ :List of 2
      .. ..$ : chr [1:3] "2|1|1|1" "2|1|1|2" "2|1|1|3"
      .. ..$ : chr [1:3] "2|1|2|1" "2|1|2|2" "2|1|2|3"
      ..$ :List of 2
      .. ..$ : chr [1:3] "2|2|1|1" "2|2|1|2" "2|2|1|3"
      .. ..$ : chr [1:4] "2|2|2|1" "2|2|2|2" "2|2|2|3" "2|2|2|4"
      ..$ :List of 2
      .. ..$ : chr [1:3] "2|3|1|1" "2|3|1|2" "2|3|1|3"
      .. ..$ : chr [1:3] "2|3|2|1" "2|3|2|2" "2|3|2|3"
     $ :List of 3
      ..$ :List of 2
      .. ..$ : chr [1:3] "3|1|1|1" "3|1|1|2" "3|1|1|3"
      .. ..$ : chr [1:3] "3|1|2|1" "3|1|2|2" "3|1|2|3"
      ..$ :List of 2
      .. ..$ : chr [1:3] "3|2|1|1" "3|2|1|2" "3|2|1|3"
      .. ..$ : chr [1:3] "3|2|2|1" "3|2|2|2" "3|2|2|3"
      ..$ :List of 2
      .. ..$ : chr [1:3] "3|3|1|1" "3|3|1|2" "3|3|1|3"
      .. ..$ : chr [1:3] "3|3|2|1" "3|3|2|2" "3|3|2|3"
    

    示例 2 这是一个深度不同且缺乏平衡性的列表示例:

    L <- list(list(1:3, 5:7), 9:10)
    

    给予:

    > str( indexer(L) )
    List of 2
     $ :List of 2
      ..$ : chr [1:3] "1|1|1" "1|1|2" "1|1|3"
      ..$ : chr [1:3] "1|2|1" "1|2|2" "1|2|3"
     $ : chr [1:2] "2|1" "2|2"
    

    【讨论】:

      【解决方案2】:

      我们可以使用melt(来自reshape2)将嵌套的list转换为具有索引列('L1'、'L2'、'L3')和'value'列的data.frame ,将其转换为data.tablesetDT(...)),按'L1'、'L2'、'L3'分组,我们得到行序列(1:.N)、paste与@987654328行的元素@ 到单个vector,然后通过指定skeletonrelist 到具有与“dico”相同结构的list

      library(data.table)
      library(reshape2)
      dico2 <- relist(do.call(paste, c(setDT(melt(dico))[, 1:.N ,
                by =  .(L1, L2, L3)], sep="|")), skeleton = dico)
      dico2
      #[[1]]
      #[[1]][[1]]
      #[[1]][[1]][[1]]
      #[1] "1|1|1|1" "1|1|1|2" "1|1|1|3" "1|1|1|4"
      
      #[[1]][[1]][[2]]
      #[1] "1|1|2|1" "1|1|2|2" "1|1|2|3" "1|1|2|4"
      
      #...
      
      #[[3]][[3]]
      #[[3]][[3]][[1]]
      #[1] "3|3|1|1" "3|3|1|2" "3|3|1|3"
      
      #[[3]][[3]][[2]]
      #[1] "3|3|2|1" "3|3|2|2" "3|3|2|3"
      

      【讨论】:

        猜你喜欢
        • 2022-11-12
        • 2011-01-25
        • 1970-01-01
        • 1970-01-01
        • 2023-02-04
        • 2018-09-20
        • 2013-01-17
        • 2023-02-06
        • 1970-01-01
        相关资源
        最近更新 更多