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

时间:2018-01-28 21:14:52

标签: r tidyverse purrr

 library(tidyverse)

使用下面的样本数据集(201603为三个,201602为三个),我尝试使用两个主数据集通过使用tidyverse工具过滤其他几个数据集,如dplyr :: semi_join,purrr :: map2和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"))

一切都在这里工作,但现在我有另一个名为&#34; MainData201602&#34;的主数据集,以及需要过滤的另外两个数据集,&#34; One201602&#34;和&# 34; Two201602&#34 ;.我可以简单地按照上面的相同步骤,但我不想重复代码,我觉得使用诸如pmap()之类的purrr工具一步一步完成所有操作都会更加优雅。我正在思考类似下面代码的内容,但这些内容并不起作用。我尝试了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

1 个答案:

答案 0 :(得分:0)

这是一个可能的解决方案。我们的想法是使用适当的名称创建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