如何使用 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
这是一个可能的解决方案。这个想法是用专有名称创建 List1
和 List2
。然后创建一个名为 target
的列表,其中包含 List1
和 List2
,以及一个名为 master
的列表,其中包含 list(MainData201603)
和 list(MainData201602)
。之后,我们可以使用map2
将您开发的map2
函数应用到target
和master
。
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
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
这是一个可能的解决方案。这个想法是用专有名称创建 List1
和 List2
。然后创建一个名为 target
的列表,其中包含 List1
和 List2
,以及一个名为 master
的列表,其中包含 list(MainData201603)
和 list(MainData201602)
。之后,我们可以使用map2
将您开发的map2
函数应用到target
和master
。
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