Предположим, у вас есть фрейм данных с переменными с именами 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)

Это, однако, вернет следующую ошибку:

Error in UseMethod("recode") : 
  no applicable method for 'recode' applied to an object of class "c('tbl_df', 'tbl', 'data.frame')"

Это связано с тем, что для перекодирования необходимо использовать вектор в качестве аргумента. Так как же это обойти?

2
J. Doe 16 Фев 2020 в 12:42

2 ответа

Лучший ответ

mutate_at полностью разработан, чтобы принимать функции, которые принимают векторы в качестве аргумента, например recode, это не проблема. Ваша ошибка заключается в том, что вы не используете помощники выбора в качестве логических вызовов, связанных с &, а вместо этого объединяете их в цепочку с помощью , в vars().

Кроме того, если вы хотите получить то, к чему стремились, вы можете использовать matches для выбора только столбцов, начинающихся с X и заканчивающихся определенными числами.

library(dplyr)

set.seed(123)
df <- data.frame("X1" = sample(1:5, 10, TRUE),
                 "X2" = sample(1:5, 10, TRUE),
                 "X3" = sample(1:5, 10, TRUE)) 
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 %>%
  mutate_at(vars(matches("^X.*1|2$")),
            recode, "1" = 5, "2" = 4, "3" = 3,"4" = 2, "5" = 1)
#>    X1 X2 X3
#> 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
3
caldwellst 17 Фев 2020 в 18:25

Одним из вариантов является подстановка имен столбцов, а затем выполните mutate_if:

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
0
StupidWolf 16 Фев 2020 в 19:29