使用 Purrr::map2 循环遍历两个列名向量,以便有条件地将多个列重新编码为新变量
Using Purrr::map2 to Loop Over Two Vectors of Column Names in Order to Conditionally Recode Multiple Columns into New Variables
library(tidyverse)
使用下面的示例代码,我想使用 "mutate" 或 "mutate_at" 根据另一列的值将多个列重新编码为新列。基本上,我想根据相应的非 "s" 变量的值重新编码结尾为 "s"(q25s、q26s 等...)的变量。因此,例如,如果 q25 = 1,则 q25s 将被重新编码,以便 1 = 0、2=0、3=0、4=1、5=1 和 88=Missing,新名称将是 q25_new.如果 q25 不等于 1,则不应重新编码并且 q25_new 应该只是 NA。
但是,为了实现这一点,我尝试使用 tidyverse 创建列名的命名向量,然后将 "mutate"、"recode" 和 "if_else" 与purr::map2。
我在想像下面的代码这样的东西应该可行吗?我不能完全让它工作......我觉得我需要在某处使用 "paste0" 来命名所有以“_new”开头的新列变量名称。
cols1<-Df %>%select(q25:q29)
cols2<-Df %>% select(q25s:q29s)
Df<- Df %>% map2(Df[cols1],Df[cols2],
~if_else(.x==1, mutate_at(vars (.y),funs(recode(.,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1),"NA"))))
这是示例代码。
Here is the sample code:
q25<-c(2,1,88,2,1)
q26<-c(2,88,88,88,2)
q27<-c(2,2,1,1,1)
q28<-c(88,1,1,2,2)
q29<-c(1,1,1,2,2)
q25s<-c(3,5,88,4,1)
q26s<-c(4,4,5,5,1)
q27s<-c(3,3,4,1,4)
q28s<-c(4,5,88,1,3)
q29s<-c(88,88,3,4,4)
Df<-data.frame(q25,q26,q27,q28,q29,q25s,q26s,q27s,q28s,q29s)
这行得通吗?
map2(Df[1:5],Df[6:10], ~ if_else(.x==1, recode(.y,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1,`88` = NA_real_),NA_real_)) %>%
as.data.frame %>%
rename_all(paste0,"_new") %>%
cbind(Df,.)
# q25 q26 q27 q28 q29 q25s q26s q27s q28s q29s q25_new q26_new q27_new q28_new q29_new
# 1 2 2 2 88 1 3 4 3 4 88 3 4 3 4 NA
# 2 1 88 2 1 1 5 4 3 5 88 1 4 3 1 NA
# 3 88 88 1 1 1 88 5 4 88 3 88 5 1 NA 0
# 4 2 88 1 2 2 4 5 1 1 4 4 5 0 1 4
# 5 1 2 1 2 2 1 1 4 3 4 0 1 1 3 4
好吧,最后我无法抗拒挑战,所以这是几乎 100% 整洁的方法(相同的输出):
library(tidyr)
Df %>%
mutate(n=row_number()) %>%
gather(key,value,-n) %>%
mutate(key2 = ifelse(grepl("s",key),"s","x"),
key=sub("s","",key)) %>%
spread(key2,value) %>%
mutate(`_new` = if_else(x==1, recode(s,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1,`88` = NA_real_),Inf)) %>%
gather(key3,value,s,x,`_new`) %>%
unite(key,key,key3,sep="") %>%
spread(key,value) %>%
rename_all(~gsub("x","",.x)) %>%
select(order(nchar(names(.))),-n)
library(tidyverse)
使用下面的示例代码,我想使用 "mutate" 或 "mutate_at" 根据另一列的值将多个列重新编码为新列。基本上,我想根据相应的非 "s" 变量的值重新编码结尾为 "s"(q25s、q26s 等...)的变量。因此,例如,如果 q25 = 1,则 q25s 将被重新编码,以便 1 = 0、2=0、3=0、4=1、5=1 和 88=Missing,新名称将是 q25_new.如果 q25 不等于 1,则不应重新编码并且 q25_new 应该只是 NA。
但是,为了实现这一点,我尝试使用 tidyverse 创建列名的命名向量,然后将 "mutate"、"recode" 和 "if_else" 与purr::map2。
我在想像下面的代码这样的东西应该可行吗?我不能完全让它工作......我觉得我需要在某处使用 "paste0" 来命名所有以“_new”开头的新列变量名称。
cols1<-Df %>%select(q25:q29)
cols2<-Df %>% select(q25s:q29s)
Df<- Df %>% map2(Df[cols1],Df[cols2],
~if_else(.x==1, mutate_at(vars (.y),funs(recode(.,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1),"NA"))))
这是示例代码。
Here is the sample code:
q25<-c(2,1,88,2,1)
q26<-c(2,88,88,88,2)
q27<-c(2,2,1,1,1)
q28<-c(88,1,1,2,2)
q29<-c(1,1,1,2,2)
q25s<-c(3,5,88,4,1)
q26s<-c(4,4,5,5,1)
q27s<-c(3,3,4,1,4)
q28s<-c(4,5,88,1,3)
q29s<-c(88,88,3,4,4)
Df<-data.frame(q25,q26,q27,q28,q29,q25s,q26s,q27s,q28s,q29s)
这行得通吗?
map2(Df[1:5],Df[6:10], ~ if_else(.x==1, recode(.y,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1,`88` = NA_real_),NA_real_)) %>%
as.data.frame %>%
rename_all(paste0,"_new") %>%
cbind(Df,.)
# q25 q26 q27 q28 q29 q25s q26s q27s q28s q29s q25_new q26_new q27_new q28_new q29_new
# 1 2 2 2 88 1 3 4 3 4 88 3 4 3 4 NA
# 2 1 88 2 1 1 5 4 3 5 88 1 4 3 1 NA
# 3 88 88 1 1 1 88 5 4 88 3 88 5 1 NA 0
# 4 2 88 1 2 2 4 5 1 1 4 4 5 0 1 4
# 5 1 2 1 2 2 1 1 4 3 4 0 1 1 3 4
好吧,最后我无法抗拒挑战,所以这是几乎 100% 整洁的方法(相同的输出):
library(tidyr)
Df %>%
mutate(n=row_number()) %>%
gather(key,value,-n) %>%
mutate(key2 = ifelse(grepl("s",key),"s","x"),
key=sub("s","",key)) %>%
spread(key2,value) %>%
mutate(`_new` = if_else(x==1, recode(s,`1`=0,`2`=0,`3`=0,`4`=1,`5`=1,`88` = NA_real_),Inf)) %>%
gather(key3,value,s,x,`_new`) %>%
unite(key,key,key3,sep="") %>%
spread(key,value) %>%
rename_all(~gsub("x","",.x)) %>%
select(order(nchar(names(.))),-n)