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

时间:2019-02-07 21:46:49

标签: r purrr

我有一个data.frame,其中包含政府中的各方。这些参与方嵌套在按时期(=每年)分组的列表列中。

我想比较每个政府与先前政府之间的重叠之处。

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 个答案:

答案 0 :(得分:1)

我认为下面的语法更加清晰,调试起来也更加方便,因为您可以在第一个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)
      }
    )
  )