purrr: как пересечь один список с несколькими вложенными списками - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть 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 и сравнить список, содержащий партии нынешнего правительства, с (вложенными) списками, содержащими партии предыдущих правительств (пред.Govs).К сожалению, здесь я застреваю.

Неудачные подходы:

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 голосов
/ 08 февраля 2019

Я думаю, что приведенный ниже синтаксис более понятен и более удобен для отладки, поскольку вы можете создать точку останова внутри первого блока кода 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)
      }
    )
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...