如何使用 Purrr 的 Pmap 和 Dplyr 的两个主数据帧过滤多个数据帧 Semi_Join

How to Filter Several Dataframes Using Two Master Dataframes with Purrr's Pmap and Dplyr's Semi_Join

 library(tidyverse)

使用下面的示例数据集(3 个用于 201603,3 个用于 201602),我尝试使用两个主数据集通过使用 tidyverse 工具(例如 dplyr::semi_join、[=16] 来过滤其他几个数据集=],以及 purrr::pmap。我希望输出是过滤数据的列表。但是,我在尝试使用 pmap() 在一组代码中完成所有这些时遇到了困难,因此我可以输出所有过滤数据的列表。

这个例子有点复杂,我会试着分解一下。首先,我使用这段代码将需要过滤的两个“201603”数据集放入一个名为“List1”的列表中。然后我使用 purrr::map 更改 Id 列名称,以便我可以在之后使用 semi_join。

List1<-list(One201603,Two201603)%>%
map(~rename(.x,"Id"="ID"))

接下来,我使用 purrr::map2 迭代 List1 和 MainData201603 的列表,这是 201603 的主数据集,用于过滤其他两个数据集。这会输出一个列表,然后我用 purrr::set_names.

更改列表元素名称
Df<-map2(List1,list(MainData201603),semi_join,by="Id")%>%
set_names(c("One201603","Two201603"))

到目前为止一切正常,但现在我有另一个主数据集“MainData201602”,以及另外两个需要过滤的数据集“One201602”和“Two201602”。我可以简单地按照与上面相同的步骤进行操作,但我不想重复代码,而且我觉得有一种更优雅的方法可以使用 purrr 工具(例如 pmap())一步完成所有操作。我在想类似下面的代码,它不起作用。我尝试了 pmap 和列表的其他几种变体,但无法弄清楚。帮助将不胜感激!

List2<-list(One201602,Two201602)%>%
map(~rename(.x,"Id"="ID"))

 Df<-pmap(list(List1,list(KPI201603)),list(List2,list(KPI201602)),semi_join,by="Id")%>%
map(~set_names(.x,c("One201603","Two201603","One201602","Two201602")))



Id<-c(6666,3333,1111,9999,8888,5555,2222,4444)
Animal<-c("Rabbit", "Moose", "Dog", "Cat", "Squirrel", "Raccoon", "Fish", "Elephant")
MainData201603<-data_frame(Id,Animal)

ID<-c(6666,3333,4545,6767,3322,1111,8888,8876,9990,1234,7775,3445)
Person<-c("Chris","Yuki","Mike","Darren","Katrina","Camilla","Dreanna","Nathan","Aisha","Sra","Pierre","Luigi")
One201603<-data_frame(ID,Person)

ID<-c(6666,8888,4453,1243,1111,5567,4543,8898,4444,7665,7889,5554)
Person<-c("Mr.K","Ms.S","Mr.P","Mr.B","Mrs.N","Mrs.W","Mr.D","Ms.A","Ms.M","Mr.X","Mrs.Z","Ms.T")
Two201603<-data_frame(ID,Person) 

MainData201602<-MainData201603

One201602<-One201603

Two201602<-Two201603

这是一个可能的解决方案。这个想法是用专有名称创建 List1List2。然后创建一个名为 target 的列表,其中包含 List1List2,以及一个名为 master 的列表,其中包含 list(MainData201603)list(MainData201602)。之后,我们可以使用map2将您开发的map2函数应用到targetmaster

List1 <- list(One201603,Two201603)%>%
  map(~rename(.x,"Id"="ID")) %>%
  set_names(c("One201603","Two201603"))

List2 <- list(One201602,Two201602)%>%
  map(~rename(.x,"Id"="ID")) %>%
  set_names(c("One201602","Two201602"))

target <- list(List1, List2)
master <- list(list(MainData201603), list(MainData201602))

map2(target, master, ~map2(.x, .y, semi_join, by = "Id"))
[[1]]
[[1]]$One201603
# A tibble: 4 x 2
     Id Person 
  <dbl> <chr>  
1  6666 Chris  
2  3333 Yuki   
3  1111 Camilla
4  8888 Dreanna

[[1]]$Two201603
# A tibble: 4 x 2
     Id Person
  <dbl> <chr> 
1  6666 Mr.K  
2  8888 Ms.S  
3  1111 Mrs.N 
4  4444 Ms.M  


[[2]]
[[2]]$One201602
# A tibble: 4 x 2
     Id Person 
  <dbl> <chr>  
1  6666 Chris  
2  3333 Yuki   
3  1111 Camilla
4  8888 Dreanna

[[2]]$Two201602
# A tibble: 4 x 2
     Id Person
  <dbl> <chr> 
1  6666 Mr.K  
2  8888 Ms.S  
3  1111 Mrs.N 
4  4444 Ms.M