代码之家  ›  专栏  ›  技术社区  ›  Jeremy K.

从嵌套列表中提取同名向量,其中列表名称各不相同?使用purrr?

  •  0
  • Jeremy K.  · 技术社区  · 6 年前

    我必须处理递归列表中的一些数据(下面是可复制的简化示例):

    groups
    #> $group1
    #> $group1$countries
    #> [1] "USA" "JPN"
    #> 
    #> 
    #> $group2
    #> $group2$countries
    #> [1] "AUS" "GBR"
    

    数据输入代码如下:

    chars <- c("USA", "JPN")
    chars2 <- c("AUS", "GBR")
    
    group1 <- list(countries = chars)
    group2 <- list(countries = chars2)
    
    groups <- list(group1 = group1, group2 = group2)
    groups
    

    countries1 <- groups$group1$countries
    countries2 <- groups$group2$countries
    

    在这个例子中,我试图提取的底层向量总是被调用 countries ,但它们包含在change name中的列表,仅通过编号而变化。

    会有一个简单的purrr解决方案吗?还是提提弗斯溶液?或者其他解决方案?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Martin Morgan    6 年前

    在你的列表中添加一些额外的案例

    groups[["group3"]] <- list()
    groups[["group4"]] <- list(foo = letters[1:2])
    groups[["group5"]] <- list(foo = letters[1:2], countries = LETTERS[1:2])
    

    这里有一个函数,它将任何列表映射到名为“countries”的元素;它返回 NULL

    fun = function(x)
        x[["countries"]]
    

    将原始列表映射为只包含您感兴趣的元素

    interesting <- Map(fun, groups)
    

    然后把它们转换成数据帧结合使用 unlist() rep()

    df <- data.frame(
        country = unlist(interesting, use.names = FALSE),
        name = rep(names(interesting), lengths(interesting))
    )
    

    或者,使用整洁的语法,例如。,

    interesting %>% 
        tibble(group = names(.), value = .) %>% 
        unnest("value")
    

    # A tibble: 6 x 2
      group  value
      <chr>  <chr>
    1 group1 USA
    2 group1 JPN
    3 group2 AUS
    4 group2 GBR
    5 group5 A
    6 group5 B
    

    如果在解析 groups ,然后修改 fun

    fun = function(x)
        as.character(x[["countries"]])
    
        2
  •  1
  •   manotheshark    6 年前

    countries <- unlist(groups, recursive = FALSE)
    names(countries) <- sub("^\\w+(\\d+)\\.(\\w+)", "\\2\\1", names(countries), perl = TRUE)
    
    > countries
    $countries1
    [1] "USA" "JPN"
    
    $countries2
    [1] "AUS" "GBR"
    
        3
  •  1
  •   JBGruber    6 年前

    data.frame 然后 unnest

    library(dplyr)
    library(tidyr)
    groups %>% 
      tibble(group = names(groups),
             country = .) %>% 
      unnest(country) %>% 
      unnest(country)
    #> # A tibble: 4 x 2
    #>   group  country
    #>   <chr>  <chr>  
    #> 1 group1 USA    
    #> 2 group1 JPN    
    #> 3 group2 AUS    
    #> 4 group2 GBR
    

    reprex package (0.3.0版)

    因为国家隐藏了两层深,所以你必须逃跑 不需要 两次。否则我认为这很简单。

        4
  •  0
  •   Till    6 年前

    如果您真的希望将每个向量作为全局环境中的一个对象,那么purrr::map2/walk和list2env的组合将起作用。为了实现这一点,我们必须首先给列表中的国家条目单独命名,否则list2env只会一遍又一遍地覆盖同一个对象。

    library(purrr)
    groups <- 
      map2(groups, 1:length(groups), ~setNames(.x, paste0(names(.x), .y)))
    walk(groups, ~list2env(. , envir = .GlobalEnv))