Функция для создания новой переменной по нескольким условиям, используя mutate и case_when (R) - PullRequest
0 голосов
/ 16 марта 2020

Я пытаюсь создать функцию, которая будет сравнивать переменные 1 и 2 и создавать третью переменную в зависимости от их соответствия. Мне нужно сделать это> 25 раз (для разных комбинаций переменных), поэтому я хочу создать функцию, а не просто использовать mutate и case_when.

Я довольно новичок в R, так что это в основном собраны вместе из других полезных постов о переполнении стека и различных учебных пособий.

Вот что я попробовал:

determine_match <- function(df, col_a, col_b){


col_a <- enquo(col_a)
  col_b <- enquo(col_b)
  newvar <- paste0(quo_name(col_a), quo_name(col_b))
  df <- df %>% mutate(!!newvar:= case_when(
    !!col_a == '1' & !!col_b =='Yes' ~ 'Match',
    !!col_a == '0' & !! col_b == 'No' ~ 'Match',
    !!col_a == '1' & !!col_b == 'No' ~ 'No Match',
    !!col_a == '0' & !!col_b == 'Yes' ~ 'No Match',
    is.na(!!col_a) | is.na(!!col_b) ~ NA_character_,
    TRUE ~ 'Error'
  )) 
}

И я проверил это на этом наборе данных:

test1 <- c('1', '0', '1', '1', '0', NA)
test2 <- c('Yes', 'No', 'No,', NA, 'Yes', NA)
id <- c(1,2,3,4,5,6)
testing.df <- data.frame(id, test1, test2)

Я не получаю ошибок, но когда я запускаю функцию с оператором печати, он возвращает только имя строки для newvar и не меняет фактический фрейм данных.

Я также пытался testing.df %>% mutate(testing3 = funs(determine_match(testing.df, testing1, testing2))), и при тестировании3 я получаю ~determine_match(testing.df, testing1, testing2)

Не уверен, является ли проблема функцией, попыткой применить или и тем, и другим.

Надеюсь, что какая-то добрая душа может помочь, спасибо !!

1 Ответ

0 голосов
/ 16 марта 2020

Вам нужно return результат, добавить return(df) (или даже просто df) в качестве последней строки вашей функции.

Если вас не волнуют входные значения, отличные от те, которые вы явно упоминаете, ("0", "1", NA для col_a и "Yes", "No", NA для col_b), вы можете упростить условие до этого (для некоторых определения "упрощать" --- это определенно короче).

determine_match <- function(df, col_a, col_b) {
  col_a <- enquo(col_a)
  col_b <- enquo(col_b)
  newvar <- paste0(quo_name(col_a), quo_name(col_b))
  df <- df %>% mutate(
    !!newvar := 
      c("No Match", "Match")[((!!col_a == '1') == (!!col_b == 'Yes')) + 1]
    )
  return(df)
}
...