【问题标题】:Alternative for giant nested ifelse statement巨型嵌套 ifelse 语句的替代方案
【发布时间】:2020-04-27 15:39:03
【问题描述】:

我有一个如下所示的数据框:

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

我想添加一个名为“Period”的列,其值由 Period No. AND Frequency 列中的内容确定。所以:

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 语句。我想知道是否有更简洁的方法来完成我想要实现的目标?

【问题讨论】:

    标签: r if-statement nested


    【解决方案1】:

    如果条件本身是嵌套的,您只需要嵌套 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)
    

    【讨论】:

      猜你喜欢
      • 2015-08-10
      • 1970-01-01
      • 1970-01-01
      • 2013-04-02
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 2015-03-03
      • 2021-02-04
      相关资源
      最近更新 更多