代码之家  ›  专栏  ›  技术社区  ›  zoowalk

purr:如何将一个列表与多个嵌套列表相交

  •  0
  • zoowalk  · 技术社区  · 5 年前

    我有一个包含政府中各方的数据框架。这些参与方嵌套在按句点(=每年)分组的列表列中。

    我想比较一下每个政府和以前的政府之间的重叠。

    library(tidyverse)
    
    df <- tibble::tribble(
      ~period, ~party, ~seats,
            1,    "A",      2,
            1,    "B",      3,
            1,    "C",      3,
            2,    "A",      2,
            2,    "C",      3,
            3,    "C",      4,
            3,    "E",      1,
            3,    "F",      3
      )
    
    
    df1 <- df %>% 
      group_by(period) %>% 
      nest() %>% 
      mutate(gov=map(data, "party") %>% map(.,list)) %>% 
      mutate(prev.govs=map(data, "party") %>% 
               map(., list) %>%
               accumulate(.,union))
    

    为了进行比较,我创建了一个列表,其中包括每个前政府的嵌套列表。( prev.govs )应比较每个嵌套列表( intersect )包括现任政府的名单( gov )这就是我被卡住的地方。

    我试着用 map2 purrr 将包含本政府当事方的名单与包含前一政府当事方的(嵌套)名单进行打包和比较。不幸的是,我被卡住了。

    失败的方法:

    df2 <- df1%>% 
      mutate(rep=map2(.x=gov, .y=prev.govs, .f=intersect))
    
    df2 <- df1%>% 
      mutate(rep=map(gov, ~map2(., prev.govs, intersect)))
    
    df2 <- df1%>% 
      mutate(rep=modify_depth(prev.govs, 2, ~map2(.,gov, intersect)))
    #> Error in mutate_impl(.data, dots): Evaluation error: Mapped vectors must have consistent lengths:
    #> * `.x` has length 2
    #> * `.y` has length 3.
    

    我想得到的是,每个时期都有一个列表,其中包含每个前政府的嵌套列表。每个嵌套列表都包含与当前政府重叠的各方。两个清单上的一个简化案例有望使这一点充分清晰:

    new <- list(c("A" ,"C", "E", "F"))
    old <- list(c("A", "B", "C"), c("A", "C"), c("D", "E", "F"))
    
    map2(new, old, intersect)
    #> [[1]]
    #> [1] "A" "C"
    #> 
    #> [[2]]
    #> [1] "A" "C"
    #> 
    #> [[3]]
    #> [1] "E" "F"
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   lkq    5 年前

    我认为下面的语法更清晰,也更便于调试,因为您可以在第一个map2代码块中抛出一个断点,并检查数据的形状。

    df1$comparison <- map2(df1$gov, df1$prev.govs, function(curGov, prevGov) {
      map2(curGov, prevGov, intersect)
    })
    

    但是如果你想坚持 mutate ,您可以执行以下操作。但是,我认为它非常混乱,最好只使用完整命名函数。

    df1 <- df1 %>% mutate(comparison = map2(gov, prev.govs, ~map2(.x, .y, intersect)))
    
    # or better use named parameters
    
    df1 <- df1 %>%
      mutate(
        comparison = map2(
          gov, 
          prev.govs,
          function(curGov, prevGov) {
            map2(curGov, prevGov, intersect)
          }
        )
      )