问题
I have a data.frame containing parties in government. These parties are nested in a list column grouped by period (= each year).
I want to compare the overlap between each government and previous governments.
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))
To make the comparison I created a list which includes nested lists for each previous government (prev.govs
). Each nested list shoudl be compared (intersect
) with the list containing the present government (gov
). Here's where I got stuck.
I tried to use map2
of the purrr
package and compare the list containing the parties of the present gov with the (nested) lists containing parties of previous governments (prev.govs). Unfortunately, here I get stuck.
Failed approaches:
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.
What I am trying to get is for each period a list with nested lists for each previous government. Each nested list contains the parties which overlap with the present government. A simplified case on two list hopefully makes this sufficiently clear:
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:
I think the below syntax is more clear and also more convenient for debugging because you can throw a breakpoint inside the first map2 code block and check the shape of the data.
df1$comparison <- map2(df1$gov, df1$prev.govs, function(curGov, prevGov) {
map2(curGov, prevGov, intersect)
})
but if you want to stick to mutate
, you can do the following. However, I think it's very confusing and it's better maybe just use the full named function.
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)
}
)
)
来源:https://stackoverflow.com/questions/54582821/purrr-how-to-intersect-one-list-with-several-nested-lists