繁体   English   中英

如何在 Purrr:Map2 中使用 Dplyr::Select 函数

[英]How to Use Dplyr::Select Functions within Purrr:Map2 All Within a Pipe

library(tidyverse)

使用示例数据(底部),我正在尝试类似下面的代码,但我坚持使用这种策略,即使用 map2 中的 dplyr::select 函数按名称选择列。 这个特定的例子使用了正则表达式,但我想要一种方法,它也可以使用 dplyr::select 中的“contains”、“ends_with”或“starts_with”。

我意识到我可以使用下面的索引......它有效......

map2(Df[8:12],Df[3:7],~ if_else(.x != 3, recode(.y,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1),88)) %>%
as.data.frame %>%
rename_all(paste0,"_new") %>%
cbind(Df,.)

但是由于我的真实数据集有很多列名,我只想使用“select”函数来命名它们,或者使用正则表达式。 我尝试了下面代码的变体,但似乎都不起作用。 我该如何纠正?

下面的代码是第一个子集,因为我只想要我正在使用的变量,然后通过管道输入 map2。

Df<-Df%>%select(Code,Pet,matches("^q.*s$"),matches("^q.*i$"))%>%
map2(Df(matches("^q.*i$")), Df(matches("^q.*s$")), ~ if_else(.x != 1,  
recode(.y,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1),88)) %>%
as.data.frame %>%
rename_all(paste0,"_new") %>%
cbind(Df,.)

示例数据:

q25i<-c(2,1,88,2,1,2,2,2)
q26i<-c(2,88,88,88,2,2,2,1)
q27i<-c(2,2,1,1,1,1,1,2)
q28i<-c(88,1,1,2,2,2,2,88)
q29i<-c(1,1,1,2,2,1,88,2)
q25s<-c(3,5,88,4,1,4,4,5)
q26s<-c(4,4,5,5,1,4,4,3)
q27s<-c(3,3,4,1,4,5,5,3)
q28s<-c(4,5,88,1,3,2,2,2)
q29s<-c(88,88,3,4,4,3,3,2)
q25U<-c(2,4,4,4,4,4,5,4)
q26U<-c(5,4,6,5,4,3,6,7)
q27U<-c(4,3,2,3,3,3,2,1)
q28U<-c(4,3,2,3,3,2,3,1)
q29U<-c(4,3,5,5,4,3,3,2)
Code<-c("P1","AB","AB","P1","P1","CD","AAA","CD")
Pet<-c("Dog","Cat","Dog","Fish","Dog","Cat","Rabbit","Fish")

 Df<-data.frame (Code,Pet,q25U,q26U,q27U,q28U,q29U,q25i,q26i,q27i,q28i,q29i,q25s,q26s,q27s,q28s,q29s)

也许这就是你要找的:

library(dplyr)
library(purrr)

list(select(Df, matches("^q.*i$")), select(Df, matches("^q.*s$"))) %>%
  pmap( ~ if_else(.x != 1, recode(.y,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1),88)) %>%
  as.data.frame %>%
  rename_all(paste0,"_new") %>%
  cbind(Df,.)

结果:

  Code    Pet q25U q26U q27U q28U q29U q25i q26i q27i q28i q29i q25s q26s q27s q28s q29s
1   P1    Dog    2    5    4    4    4    2    2    2   88    1    3    4    3    4   88
2   AB    Cat    4    4    3    3    3    1   88    2    1    1    5    4    3    5   88
3   AB    Dog    4    6    2    2    5   88   88    1    1    1   88    5    4   88    3
4   P1   Fish    4    5    3    3    5    2   88    1    2    2    4    5    1    1    4
5   P1    Dog    4    4    3    3    4    1    2    1    2    2    1    1    4    3    4
6   CD    Cat    4    3    3    2    3    2    2    1    2    1    4    4    5    2    3
7  AAA Rabbit    5    6    2    3    3    2    2    1    2   88    4    4    5    2    3
8   CD   Fish    4    7    1    1    2    2    1    2   88    2    5    3    3    2    2
  q25i_new q26i_new q27i_new q28i_new q29i_new
1        0        1        0        1       88
2       88        1        0       88       88
3       88        1       88       88       88
4        1        1       88        0        1
5       88        0       88        0        1
6        1        1       88        0       88
7        1        1       88        0        0
8        1       88        0        0        0

笔记:

如果您使用正确的索引,这与您的结果匹配:

map2(Df[8:12],Df[13:17],~ if_else(.x != 1, recode(.y,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1),88)) %>%
  as.data.frame %>%
  rename_all(paste0,"_new") %>%
  cbind(Df,.)

使用pmap而不是map2的原因是因为pmap需要一个输入列表,而map2正好需要两个输入。 例如,以下使用map2而不是pmap

list(select(Df, matches("^q.*i$")), select(Df, matches("^q.*s$"))) %>%
  {map2(.[[1]], .[[2]], ~ if_else(.x != 1, recode(.y,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1),88))} %>%
  as.data.frame %>%
  rename_all(paste0,"_new") %>%
  cbind(Df,.)

这不太方便,IMO,因为您必须手动指定输入,并且必须用{}包装map2以将管道的%>%默认值覆盖到第一个参数中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM