Альтернатива для гигантского вложенного ifelse - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть фрейм данных, который выглядит следующим образом:

Period No.  Frequency
1           Month
2           Month
3           Month
3           Quarter
6           Quarter     
9           Quarter
1           YTD
2           YTD
3           YTD

Я хочу добавить столбец с именем «Период», значения которого определяются значениями в столбцах «Номер периода» и «Частота». Итак:

Period No.  Frequency  Period
1           Month      1
2           Month      2
3           Month      3
3           Quarter    Q1
6           Quarter    Q2 
9           Quarter    Q3
1           YTD        YTD-Jan
2           YTD        YTD-Feb
3           YTD        YTD-Mar

Сейчас я использую вложенные операторы if для этого. Например:

data$Period <-
  ifelse(
    (data$`Period No.` == '3') & (data$Frequency == 'Q1'), 'Q1',
    ifelse(
      (data$`Period No.` == '6') & (data$Frequency == 'Q2'), 'Q2',
      ifelse(
        (data$`Period No.` == '9') & (data$Frequency == 'Q3'), 'Q3', 'ERROR'
)
)
)

Если бы я делал это каждый месяц для каждой итерации частоты, у меня было бы 30 вложенных операторов ifelse. Мне интересно, есть ли более краткий способ сделать то, чего я пытаюсь достичь?

1 Ответ

2 голосов
/ 27 апреля 2020

Вы действительно должны вкладывать ifelse операторы только в том случае, если сами условия являются вложенными. В этом случае условия являются взаимоисключающими, поэтому вы можете назначить каждому набору индивидуально. Мы также можем быть немного хитрыми в создании ваших результатов с помощью paste и некоторой математики, а не перечислять все возможности:

df$Period[df$Frequency == "Month"] = as.character(df$Period_No[df$Frequency == "Month"])
df$Period[df$Frequency == "Quarter"] = paste0("Q", (df$Period_No[df$Frequency == "Quarter"] - 1) %/% 3 + 1)
df$Period[df$Frequency == "YTD"] = paste0("YTD-", month.abb[df$Period_No[df$Frequency == "YTD"]])

df
#   Period_No Frequency  Period
# 1         1     Month       1
# 2         2     Month       2
# 3         3     Month       3
# 4         3   Quarter      Q1
# 5         6   Quarter      Q2
# 6         9   Quarter      Q3
# 7         1       YTD YTD-Jan
# 8         2       YTD YTD-Feb
# 9         3       YTD YTD-Mar

Если вам нравится dplyr, я бы порекомендовал функцию case_when :

df %>% mutate(Period = case_when(
    Frequency == "Month" ~ as.character(Frequency),
    Frequency == "Quarter" ~ paste0("Q", (Period_No - 1) %/% 3 + 1),
    Frequency == "YTD" ~ paste0("YTD-", month.abb[Period_No])
))

Использование данных этого примера:

df = read.table(text = "Period_No  Frequency
1           Month
2           Month
3           Month
3           Quarter
6           Quarter     
9           Quarter
1           YTD
2           YTD
3           YTD", header = T)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...