Изменять несколько переменных на основе заданного условия

#r #dplyr

#r #dplyr

Вопрос:

У меня есть следующие данные:

   library(dplyr)

     d <- data_frame(
      region = c('all', 'nj', 'rkl', 'all'),
      figures= c(5, 7, 4, 8),
      figures2 = c(3, 5, 6, 7))
  

Я хотел бы использовать dplyr, чтобы указать, когда ‘region’ = ‘all’, затем преобразовать ‘figures’ и ‘figures2’ в ‘x’. Я не хочу использовать mutate для создания новых переменных, я хочу изменить значения в переменных, которые уже существуют. Таким образом, данные будут выглядеть следующим образом:

   d2 <- data_frame(
          region = c('all', 'nj', 'rkl', 'all'),
          figures= c(x, 7, 4, x),
          figures2 = c(x, 5, 6, x))
  

Я думаю, мне нужно что-то вроде этого:

  d %>% mutate_at(vars(1:3), funs(ifelse(region = 'all', 'x', .)))
  

Однако это не совсем работает.

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

1. d %>% mutate_at(vars(2:3), list(~ ifelse(region == 'all', 'x', .))) не тестировал, но попробуйте

2. Есть причина, по которой вы не выполняете два mutate s? Один для figures и один для figures2 ? Если у вас есть еще много таких столбцов, подумайте о gather преобразовании ваших столбцов в длинный формат.

3. вы правы — я просто сделал это до того, как вы опубликовали, и это сработало. Я удалю сообщение, поскольку на этот вопрос есть ответ в другом месте. Спасибо

Ответ №1:

Вы были на правильном пути с mutate_at :

 d %>% 
  mutate_at(vars(2:3), list(~ ifelse(region == 'all', 'x', .)))
  

Вывод:

 # A tibble: 4 x 3
  region figures figures2
  <chr>  <chr>   <chr>   
1 all    x       x       
2 nj     7       5       
3 rkl    4       6       
4 all    x       x   
  

Вы можете просто заменить 'x' числом, если это необходимо.

Редактировать.

  • Я также думаю, что это replace лучшая альтернатива, вы могли бы просто сделать d %>%
    mutate_at(vars(2:3), list(~ replace(., region == 'all', 'x')))
    то же самое;
  • Более того, как отметил @Moody_Mudskipper, нет необходимости в list новейшей dplyr версии, поэтому mutate_at(2:3, ~ ifelse(region == 'all', 'x', .)) также справился бы с этой задачей.

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

1. С последней версией dplyr вам не нужно переносить свою формулу в список для доступа к другим столбцам в mutate_at . Также нет необходимости использовать vars с числовыми индексами. Так что это нормально : d %>% mutate_at(2:3, ~ ifelse(region == 'all', 'x', .))

2. Спасибо @Moody_Mudskipper, не знал об этом — изменю это!

Ответ №2:

Один из способов с mutate и replace :

 d %>% 
  mutate(figures = replace(figures, region == 'all', 10)) %>%
  mutate(figures2 = replace(figures2, region == 'all', 10))

# A tibble: 4 x 3
  region figures figures2
  <chr>    <dbl>    <dbl>
1 all         10       10
2 nj           7        5
3 rkl          4        6
4 all         10       10
  

Я использую 10 здесь в качестве вашего x

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

1. Да, это тоже хорошо, дает немного больше контроля, если вы хотите заменить разные столбцы разными значениями

Ответ №3:

Вариантом было бы также использовать case_when

 library(dplyr)
d %>%
   mutate_if(is.numeric, list(~ case_when(region == "all" ~ 'x',
                                         TRUE ~ as.character(.) )))
# A tibble: 4 x 3
#  region figures figures2
#  <chr>  <chr>   <chr>   
#1 all    x       x       
#2 nj     7       5       
#3 rkl    4       6       
#4 all    x       x       
  

base R Компактным вариантом было бы

 d[d$region == "all", -1] <- "x"