条件重新编码 - 使用Mutate_at中的列向量以及If_else和Dplyr :: Recode

时间:2017-10-26 04:06:59

标签: r tidyverse

library(tidyverse)    

使用下面的示例代码,我想创建一个新的变量“Filter”,它根据相应的非“s”的值重新编码以“s”(q25s,q26s等...)结尾的变量“变量。因此,例如,如果q25 = 1,则将重新编码q25s,使得1 = 0,2 = 0,3 = 0,4 = 1,5 = 1,并且88 =丢失。如果q25不等于1,则Filter应为0.对于所有其他变量集,将重复此模式。

然而,为了实现这一点,我试图使用tidyverse来创建一个名为“cols”的列名称向量,然后在“mutate_at”函数中与“if_else”和dplyr :: recode一起使用它。

以下是尝试,但似乎不起作用。我该如何更正代码?我愿意接受其他建议,只要使用tidyverse并且代码紧凑,如果可能的话不超过两行......

cols<-c(q25:q29)

Df<-Df%>%mutate_at(vars(q25s:q29s),funs(Filter=if_else(!!cols=1,recode  (.,`1`="a",`2`="b",`3`="c",`4`="d",`5`="e"),"Missing")))

如何使用tidyverse实现这一目标?

以下是示例代码:

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)

1 个答案:

答案 0 :(得分:1)

一个选项是通过包含以'q'开头,后跟数字('q \ d +')和'q'后跟数字后跟's'('q \ d + s')的列来对数据集进行子集化),然后使用map2,使用ifelse根据“q \ d +”列中的值1将相应列更改为letters

library(tidyverse)
cols<-paste0("q", 25:29)
cols1 <- paste0(cols, "s")
Df[cols1] <- map2(Df[cols], Df[cols1], ~ifelse(.x == 1, letters[.y], .y) %>%
                             replace(., is.na(.), "Missing") )

Df
#  q25 q26 q27 q28 q29 q25s q26s q27s    q28s    q29s
#1   2   2   2  88   1    3    4    3       4 Missing
#2   1  88   2   1   1    e    4    3       e Missing
#3  88  88   1   1   1   88    5    d Missing       c
#4   2  88   1   2   2    4    5    a       1       4
#5   1   2   1   2   2    a    1    d       3       4

或仅使用base R

Df[cols1] <- Map(function(x,y) {
                 x1 <- ifelse(x == 1, letters[y], y)
                 replace(x1, is.na(x1), "Missing")
                 },
                      Df[cols], Df[cols1])