r - 使用 Purrr::map2 循环列名称的两个向量,以便有条件地将多个列重新编码为新变量

标签 r tidyverse purrr

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)

关于r - 使用 Purrr::map2 循环列名称的两个向量,以便有条件地将多个列重新编码为新变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46961679/

相关文章:

r - 检测我在哪台计算机上运行 R 脚本

r - 将 data.frame 列名称传递给函数

r - 检查列表中的值是否存在于多列 R data.table 中

r - 使用 tidyverse 创建一个以恒定速率增加的列

r - 使用 rowwise() 时如何处理整行?

r - Magrittr 转发管道无法将值转发到 openXL::addWorksheet - "Error ...: First argument must be a Workbook"

r - 如何使用 purrr 嵌套数据对特定行进行计算

R-创建一个新变量,其中每个观察值都依赖于另一个表和数据框中的其他变量

r - 在 purrr 中处理不同长度的向量

r - 使用向量索引 R 中的 data.frame