条件重新编码 - 使用 Mutate_at 内的列向量以及 If_else 和 Dplyr::Recode
Conditional Recoding - Using a Vector of Columns within Mutate_at Together with If_else and Dplyr::Recode
library(tidyverse)
使用下面的示例代码,我想创建一个新变量 "Filter",它根据值重新编码结尾为 "s"(q25s、q26s 等...)的变量相应的非 "s" 变量。因此,例如,如果 q25 = 1,则 q25s 将被重新编码,以便 1 = 0、2=0、3=0、4=1、5=1 和 88=Missing。如果 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)
一个选项是通过包括以 'q' 开头,后跟数字 ('q\d+') 和 'q' 后跟数字和 's' 开头的列来对数据集进行子集化('q\d+s'),然后用map2
,根据'q\d+'列
中的值1,使用ifelse
将相应的列更改为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])
library(tidyverse)
使用下面的示例代码,我想创建一个新变量 "Filter",它根据值重新编码结尾为 "s"(q25s、q26s 等...)的变量相应的非 "s" 变量。因此,例如,如果 q25 = 1,则 q25s 将被重新编码,以便 1 = 0、2=0、3=0、4=1、5=1 和 88=Missing。如果 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)
一个选项是通过包括以 'q' 开头,后跟数字 ('q\d+') 和 'q' 后跟数字和 's' 开头的列来对数据集进行子集化('q\d+s'),然后用map2
,根据'q\d+'列
ifelse
将相应的列更改为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])