dplyr-一次对多个列重新编码

dplyr-一次对多个列重新编码,r,dplyr,R,Dplyr,假设您有一个名为X1-X30和Y1-Y30的数据帧。这些变量中的每一个都包含整数1-5。我们希望重新编码一些以X开头的变量,如下所示: df %<>% mutate_at(vars(starts_with("X") & ends_with("5", "8", "16", "22", "28")), recode, "1" = 5, "2" = 4, "4" = 2, "5" = 1) 这是因为recod

假设您有一个名为X1-X30和Y1-Y30的数据帧。这些变量中的每一个都包含整数1-5。我们希望重新编码一些以X开头的变量,如下所示:

df %<>%
   mutate_at(vars(starts_with("X") & 
                  ends_with("5", "8", "16", "22", "28")), 
             recode, "1" = 5, "2" = 4, "4" = 2, "5" = 1)

这是因为recode需要将向量作为参数。那么,绕过这个问题的方法是什么呢?

mutate\u at
完全是为了采用以向量为参数的函数,比如
recode
,这不是问题所在。您的错误只是因为您没有将select HELPER用作与
&
链接的逻辑调用,而是使用
vars()
中链接它们

此外,如果您想要达到您的目标,您可能希望使用
匹配
只选择以X开头、以特定数字结尾的列

库(dplyr)
种子集(123)
dfx1x2x3
#> 1   3  5  2
#> 2   3  3  1
#> 3   2  3  3
#> 4   2  1  4
#> 5   3  4  1
#> 6   5  1  3
#> 7   4  1  5
#> 8   1  5  4
#> 9   2  3  2
#> 10  3  2  5
df%>%
在(变量(匹配项(^X.*1 | 2$))处进行变异,
重新编码,“1”=5,“2”=4,“3”=3,“4”=2,“5”=1)
#>x1x2x3
#> 1   3  1  2
#> 2   3  3  1
#> 3   4  3  3
#> 4   4  5  4
#> 5   3  2  1
#> 6   1  5  3
#> 7   2  5  5
#> 8   5  1  4
#> 9   4  3  2
#> 10  3  4  5

一个选项是对colname进行子串,然后在出现以下情况时进行
变异:

set.seed(111)
df = data.frame(matrix(round(runif(60*4,min=1,max=5)),ncol=60))
colnames(df) = c(paste0("X",1:30),paste0("Y",1:30))

start_X = substr(colnames(df),1,1) == "X"
ends_w = substr(colnames(df),2,nchar(colnames(df))) %in% c("5", "8", "16", "22", "28")

df %>% 
mutate_if(start_X & ends_w,
recode, "1" = 5, "2" = 4, "4" = 2, "5" = 1) %>%
select(c("X5","X8","X16","X22","X28"))

  X5 X8 X16 X22 X28
1  4  2   5   5   3
2  1  3   3   4   1
3  4  5   4   2   4
4  3  3   4   2   2

df %>% select(c("X5","X8","X16","X22","X28"))
  X5 X8 X16 X22 X28
1  2  4   1   1   3
2  5  3   3   2   5
3  2  1   2   4   2
4  3  3   2   4   4

添加2021年更新的解决方案,包括取代mutate_*函数的
函数以及regex和
tidy_选择
替代方案

库(dplyr)
种子集(123)
(df X1 X2 X3
#> 1   3  5  2
#> 2   3  3  1
#> 3   2  3  3
#> 4   2  1  4
#> 5   3  4  1
#> 6   5  1  3
#> 7   4  1  5
#> 8   1  5  4
#> 9   2  3  2
#> 10  3  2  5
用正则表达式
df%>%
变异(跨越(匹配项(“^X.*1 | 2$”),
重新编码,“1”=5,“2”=4,“3”=3,“4”=2,“5”=1))
#>x1x2x3
#> 1   3  1  2
#> 2   3  3  1
#> 3   4  3  3
#> 4   4  5  4
#> 5   3  2  1
#> 6   1  5  3
#> 7   2  5  5
#> 8   5  1  4
#> 9   4  3  2
#> 10  3  4  5
没有正则表达式
df%>%
变异(交叉((以“X”开头,以(如字符(1:2))结尾),
重新编码,“1”=5,“2”=4,“3”=3,“4”=2,“5”=1))
#>x1x2x3
#> 1   3  1  2
#> 2   3  3  1
#> 3   4  3  3
#> 4   4  5  4
#> 5   3  2  1
#> 6   1  5  3
#> 7   2  5  5
#> 8   5  1  4
#> 9   4  3  2
#> 10  3  4  5

但是变量Y1不是也会被你的代码选中吗,而我只想选择X1?@J.Doe,只要它不以X开头,而不是以X开头。刚才注意到,请参见上文如何使用
matches
更好地选择带有regex的列。你也可以通过
df%>%mutate\u at(vars(matches(“^X.*1 | 2$”)跳过重编码部分,~abs(-5)+1)
。谢谢!我更喜欢不带正则表达式的解决方案,因此我将等待,看看是否会出现不带正则表达式的答案;如果没有,这将被接受。
set.seed(111)
df = data.frame(matrix(round(runif(60*4,min=1,max=5)),ncol=60))
colnames(df) = c(paste0("X",1:30),paste0("Y",1:30))

start_X = substr(colnames(df),1,1) == "X"
ends_w = substr(colnames(df),2,nchar(colnames(df))) %in% c("5", "8", "16", "22", "28")

df %>% 
mutate_if(start_X & ends_w,
recode, "1" = 5, "2" = 4, "4" = 2, "5" = 1) %>%
select(c("X5","X8","X16","X22","X28"))

  X5 X8 X16 X22 X28
1  4  2   5   5   3
2  1  3   3   4   1
3  4  5   4   2   4
4  3  3   4   2   2

df %>% select(c("X5","X8","X16","X22","X28"))
  X5 X8 X16 X22 X28
1  2  4   1   1   3
2  5  3   3   2   5
3  2  1   2   4   2
4  3  3   2   4   4