как использовать mutate_if для изменения значений

#r #dplyr

Вопрос:

Как я могу использовать mutate_if() для изменения значений b to NA в случае a > 25

Я могу это сделать, ifelse но я чувствую mutate_if , что создан для такой задачи.

 library(tidyverse)

tbl <- tibble(a = c(10, 20, 30, 40, 10, 60),
              b = c(12, 23, 34, 45, 56, 67))
 

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

1. Может case_when() быть, или if_else() было бы лучше для этого примера.

2. mutate_if предназначен для выбора целых столбцов и применения к ним некоторой операции. Он не применяет условный оператор к отдельным элементам в столбце. mutate с ан ifelse , вероятно, это то, что вы хотите. Если вы хотите применить эту операцию к нескольким столбцам, см. across раздел .

3. хорошо, я понял, спасибо

Ответ №1:

Вариант mutate_if() применяет функцию предиката (функцию, которая возвращает значение TRUE или FALSE) для определения соответствующего подмножества столбцов. Таким образом, условие mutate_if будет применяться ко всем столбцам, и в приведенном ниже примере вы можете видеть, как оно используется. Примеры использования-выполнение математической операции над числовыми полями и т. Д.

https://dplyr.tidyverse.org/reference/mutate_all.html

 function (.tbl, .predicate, .funs, ...)

library(dplyr)

# Below code gets the job done but as Hugh Allan explained it is probably not 
  the right approach

tbl %>%
  mutate_if(colnames(tbl) != 'a', ~ifelse(a > 25, NA, .))

# A tibble: 6 x 2
      a     b
  <dbl> <dbl>
1    10    12
2    20    23
3    30    NA
4    40    NA
5    10    56
6    60    NA
 

Ответ №2:

В этом небольшом примере я не уверен, что вам это действительно нужно mutate_if() . mutate_if предназначен для использования _if детали для определения того, какие столбцы подмножествовать и над чем работать, а не if условия при изменении значения.

Скорее, вы можете использовать mutate_at() для выбора столбцов для работы — либо на основе их точного названия, либо с помощью vars(contains('your_string')) .

Дополнительную информацию о функциях см. на странице справки mutate_* : https://dplyr.tidyverse.org/reference/mutate_all.html

Вот 3 варианта, используя mutate() и mutate_at() :

 # using mutate()
tbl %>% 
  mutate(
    b = ifelse(a > 25, NA, b)
  )

# mutate_at - we select only column 'b'
tbl %>% 
  mutate_at(vars(c('b')), ~ifelse(a > 25, NA, .))

# select only columns with 'b' in the col name
tbl %>% 
  mutate_at(vars(contains('b')), ~ifelse(a > 25, NA, .))
 

Которые все дают одинаковый результат:

 # A tibble: 6 x 2
      a     b
  <dbl> <dbl>
1    10    12
2    20    23
3    30    NA
4    40    NA
5    10    56
6    60    NA
 

Я знаю , что это не mutate_if так, но я подозреваю, что на самом деле вам это не нужно.

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

1. mutate_if , mutate_all , и mutate_at заменяются в пользу mutate с across

2. Да, это правда, я скоро должен переключиться!

Ответ №3:

Мы можем использовать replace

 library(dplyr)
tbl %>%
      mutate(b = replace(b, a > 25, NA))
 

-выход

 # A tibble: 6 x 2
      a     b
  <dbl> <dbl>
1    10    12
2    20    23
3    30    NA
4    40    NA
5    10    56
6    60    NA
 

Ответ №4:

А для завершения вот база R и data.table вариант.

 tbl$b[tbl$a > 25] <- NA
tbl

#     a     b
#  <dbl> <dbl>
#1    10    12
#2    20    23
#3    30    NA
#4    40    NA
#5    10    56
#6    60    NA
 

В data.table

 library(data.table)
setDT(tbl)
tbl[a > 25, b := NA]
tbl