Как изменить 1, 2, 3, 4 на 0, 1 в нескольких столбцах?

#r #case #dplyr #tibble

Вопрос:

Существует тиббл, который содержит числа от 1 до 4.

 library(tidyverse)

# reproducible data
sample_tbl <- structure(list(X1 = c(4L, 4L, 1L, 4L, 1L, 4L, 2L, 3L, 2L, 4L), 
X2 = c(1L, 4L, 4L, 4L, 4L, 2L, 4L, 4L, 3L, 2L), X3 = c(4L, 
3L, 3L, 3L, 2L, 2L, 1L, 1L, 4L, 2L), X4 = c(1L, 4L, 3L, 2L, 
3L, 4L, 2L, 1L, 1L, 1L), X5 = c(1L, 3L, 3L, 1L, 2L, 2L, 3L, 
3L, 4L, 1L), X6 = c(2L, 3L, 4L, 4L, 3L, 2L, 4L, 1L, 1L, 3L
), X7 = c(3L, 4L, 1L, 2L, 3L, 3L, 2L, 2L, 2L, 1L), X8 = c(2L, 
4L, 4L, 2L, 3L, 2L, 3L, 4L, 3L, 4L), X9 = c(2L, 1L, 4L, 4L, 
2L, 4L, 4L, 1L, 3L, 3L), X10 = c(3L, 4L, 1L, 3L, 1L, 2L, 
1L, 2L, 2L, 3L)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -10L))

# A tibble: 10 x 10
      X1    X2    X3    X4    X5    X6    X7    X8    X9   X10
   <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
 1     4     1     4     1     1     2     3     2     2     3
 2     4     4     3     4     3     3     4     4     1     4
 3     1     4     3     3     3     4     1     4     4     1
 4     4     4     3     2     1     4     2     2     4     3
 5     1     4     2     3     2     3     3     3     2     1
 6     4     2     2     4     2     2     3     2     4     2
 7     2     4     1     2     3     4     2     3     4     1
 8     3     4     1     1     3     1     2     4     1     2
 9     2     3     4     1     4     1     2     3     3     2
10     4     2     2     1     1     3     1     4     3     3
 

Я хочу изменить 1 и 2 на 0, а 3 на 4 на 1.

Ожидаемые результаты:

 # A tibble: 10 x 10
      X1    X2    X3
   <int> <int>   ...
 1     1     0   ... 
 2     1     1   ... 
 3     0     1   ...
 4     1     1   ...
 5     0     1   ...
 6     1     0   ...
 7     0     1   ...
 8     1     1   ...
 9     0     1   ...
10     1     0   ...
 

Я думал, что смогу использовать dplyr::mutate() dplyr::across() , dplyr::case_when() но не могу понять, как.

Как я могу это сделать?

Ответ №1:

Использование целочисленного деления на 3:

 sample_tbl %/% 3

#    X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# 1   1  0  1  0  0  0  1  0  0   1
# 2   1  1  1  1  1  1  1  1  0   1
# 3   0  1  1  1  1  1  0  1  1   0
# 4   1  1  1  0  0  1  0  0  1   1
# 5   0  1  0  1  0  1  1  1  0   0
# 6   1  0  0  1  0  0  1  0  1   0
# 7   0  1  0  0  1  1  0  1  1   0
# 8   1  1  0  0  1  0  0  1  0   0
# 9   0  1  1  0  1  0  0  1  1   0
# 10  1  0  0  0  0  1  0  1  1   1
 

Ответ №2:

Мы можем зациклить across столбец, создать логический вектор с %in% вектором значений 3, 4 и принудить его к двоичному

 library(dplyr)
sample_tbl <- sample_tbl %>% 
       mutate(across(everything(),  ~  (. %in% c(3, 4))))
 

-выход

 sample_tbl
# A tibble: 10 x 10
      X1    X2    X3    X4    X5    X6    X7    X8    X9   X10
   <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
 1     1     0     1     0     0     0     1     0     0     1
 2     1     1     1     1     1     1     1     1     0     1
 3     0     1     1     1     1     1     0     1     1     0
 4     1     1     1     0     0     1     0     0     1     1
 5     0     1     0     1     0     1     1     1     0     0
 6     1     0     0     1     0     0     1     0     1     0
 7     0     1     0     0     1     1     0     1     1     0
 8     1     1     0     0     1     0     0     1     0     0
 9     0     1     1     0     1     0     0     1     1     0
10     1     0     0     0     0     1     0     1     1     1
 

Если нам нужно использовать case_when

 sample_tbl <- sample_tbl %>%
      mutate(across(everything(), ~ case_when(. %in% c(3, 4) ~ 1, 
             . %in% c(1, 2) ~ 0)))
 

Или с помощью base R

 sample_tbl[] <- lapply(sample_tbl, (x)   (x %in% c(3, 4)))
 

данные

 sample_tbl <- structure(list(X1 = c(4L, 4L, 1L, 4L, 1L, 4L, 2L, 3L, 2L, 4L), 
    X2 = c(1L, 4L, 4L, 4L, 4L, 2L, 4L, 4L, 3L, 2L), X3 = c(4L, 
    3L, 3L, 3L, 2L, 2L, 1L, 1L, 4L, 2L), X4 = c(1L, 4L, 3L, 2L, 
    3L, 4L, 2L, 1L, 1L, 1L), X5 = c(1L, 3L, 3L, 1L, 2L, 2L, 3L, 
    3L, 4L, 1L), X6 = c(2L, 3L, 4L, 4L, 3L, 2L, 4L, 1L, 1L, 3L
    ), X7 = c(3L, 4L, 1L, 2L, 3L, 3L, 2L, 2L, 2L, 1L), X8 = c(2L, 
    4L, 4L, 2L, 3L, 2L, 3L, 4L, 3L, 4L), X9 = c(2L, 1L, 4L, 4L, 
    2L, 4L, 4L, 1L, 3L, 3L), X10 = c(3L, 4L, 1L, 3L, 1L, 2L, 
    1L, 2L, 2L, 3L)), row.names = c(NA, -10L), class = c("tbl_df", 
"tbl", "data.frame"))
 

Комментарии:

1. В чем проблема с использованием ваших данных?

2. @zx8754 ну, вы можете добавить данные в свой пост, а не ссылаться на мой пост.

3. Зачем дублировать усилия?

4. Тогда мой ответ пострадает, и что все в порядке, так как операция не предоставила воспроизводимых данных, решение то же самое.

5. Я отредактировал сообщение ОП и добавил воспроизводимые данные, нет, я не копировал его из вашего ответа.

Ответ №3:

Вот базовый вариант R.

Измените 1 и 2 на 0, а остальные значения на 1.

 sample_tbl[sample_tbl == 1 | sample_tbl == 2] <- 0
sample_tbl[sample_tbl != 0] <- 1
sample_tbl

#      X1    X2    X3    X4    X5    X6    X7    X8    X9   X10
#   <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
# 1     1     1     1     1     1     0     0     1     1     1
# 2     0     1     0     0     1     1     0     1     1     1
# 3     1     1     0     1     0     1     1     0     1     0
# 4     1     1     1     1     1     1     1     0     0     1
# 5     1     0     1     1     0     1     1     1     0     0
# 6     1     1     0     1     1     1     1     1     0     1
# 7     0     1     1     0     1     1     0     0     0     1
# 8     1     1     0     1     0     0     1     1     0     1
# 9     1     0     1     1     1     1     1     1     1     1
#10     0     1     1     1     0     1     1     0     1     0