Альтернатива вложенным операторам If Else
Я работаю с данными бейсбола Retrosheet в R и пытаюсь создать отдельный столбец (используя функцию mutate в dplyr), который предупреждает меня, начиналась ли одна строка из существующего столбца с "двумя ударами" или "тремя шарами" ". Например:
PITCH_SEQ_TX <- c('SSSC', 'FFBB', 'BBSSC', 'BBBSB', 'CBSFFFS')
Разработчики Retrosheet перечисляют только один символ для шаров ("b"), но несколько для ударов (то есть "c", "f", "l", "m", "s", "t"). Таким образом, если бы я хотел собрать из вышеприведенной строки, какие последовательности начинаются с двух ударов или трех шаров, я бы использовал:
PITCH_SEQ_TX_Updated <- mutate(PITCH_SEQ_TX, Cutoff = ifelse(grepl("^BBB", PITCH_SEQ_TX),
"Three Balls", ifelse(grepl("^SS", updated_PITCH_SEQ_TX), "Two Strikes",
ifelse(grepl("^FF", PITCH_SEQ_TX), "Two Strikes", "NA"))))
ОДНАКО существует слишком много различных комбинаций двух ударов (т. Е. Cc, cs, ff и т. Д.), Которые не позволяют мне использовать вложенные операторы if else по всему набору данных (я получаю сообщение об ошибке: переполнение контекстного заголовка в строке 17 с предупреждением при переходе последние 50 разных комбинаций). Есть ли альтернативная функция, которая позволила бы мне сжать мой существующий код, используя ли ifelse или какую-либо другую функцию, которая позволила бы мне обойти эту проблему? Любая помощь будет оценена.
2 ответа
Вы можете использовать набор символов в регулярных выражениях для идентификатора ударов, указав их в квадратных скобках, например: [ABC]
, который будет соответствовать любому персонажу A
, B
, или же C
, Это будет означать, что вам не нужно выписывать каждую категорию отдельно. Например:
grepl("^[CFLMST]{2,}", PITCH_SEQ_TX)
#[1] TRUE TRUE FALSE FALSE FALSE
grepl("^B{3,}", PITCH_SEQ_TX)
#[1] FALSE FALSE FALSE TRUE FALSE
Основываясь на ответе @thelatemail, в сочетании с комментарием mt1022 для использования case_when
а также mutate
, вот полностью проработанный пример, используя функции из stringr
для текстовой работы.
library(dplyr)
library(stringr)
# make vector of pitch sequence data
PITCH_SEQ_TX <- c('SSSC', 'FFBB', 'BBSSC', 'BBBSB', 'CBSFFFS')
# make another variable of the number of pitches in each sequence
# this is just so we have two variables for a df
NUM_PITCHES <- stringr::str_count(PITCH_SEQ_TX)
# make a df
BB <- dplyr::tibble(PITCH_SEQ_TX, NUM_PITCHES)
# create the recoded pitch sequence variable - PITCH_SEQ_TX_UPDATED
BB %>%
dplyr::mutate(PITCH_SEQ_TX_UPDATED =
dplyr::case_when(
stringr::str_detect(string = PITCH_SEQ_TX, pattern = "^[CFLMST]{2,}") ~ "Two strikes",
stringr::str_detect(string = PITCH_SEQ_TX, pattern = "^B{3,}") ~ "Three balls"
)
)
# A tibble: 5 x 3
PITCH_SEQ_TX NUM_PITCHES PITCH_SEQ_TX_UPDATED
<chr> <int> <chr>
1 SSSC 4 Two strikes
2 FFBB 4 Two strikes
3 BBSSC 5 <NA>
4 BBBSB 5 Three balls
5 CBSFFFS 7 <NA>