【问题标题】:How to optimize codes present in if, else if and else conditions [closed]如何优化 if、else if 和 else 条件中存在的代码 [关闭]
【发布时间】:2022-01-24 03:54:45
【问题描述】:

查看代码,您会发现我使用了ifelse ifelse 条件。请注意,对于这两个条件,一些代码非常相似,一般情况下,条件之间的变化如下:group_by 来自第一个 inner_join 来自第一个 SPVfilter 来自第二个SPV。有什么办法可以优化这段代码,这样我就不需要在两种情况下重复类似的代码了?

library(dplyr)
library(tidyverse)
library(lubridate)

df1 <- structure(
  list(date1= c("2021-06-28","2021-06-28","2021-06-28","2021-06-28"),
       date2 = c("2021-06-23","2021-06-24","2021-06-30","2021-07-01"),
       DTT= c("Hol","Hol","Hol",0),
       Week= c("Wednesday","Thursday","Wednesday","Thursday"),
       Category = c("ABC","FDE","ABC","FDE"),
       DR1 = c(4,1,1,2),
       DR01 = c(4,1,2,3), DR02= c(4,2,0,2),DR03= c(9,5,0,1),
       DR04 = c(5,4,3,2),DR05 = c(5,4,0,2)),
  class = "data.frame", row.names = c(NA, -4L))

dmda<-"2021-07-01"
CategoryChosse<-"FDE"
DTest<-"0"
Wk<-"Thursday"

Dx<-subset(df1,df1$date2<df1$date1)

x<-Dx %>% select(starts_with("DR0"))

x<-cbind(Dx, setNames(Dx$DR1 - x, paste0(names(x), "_PV")))

PV<-select(x, date2,Week, Category, DTT, DR1, ends_with("PV"))


if(any(PV$DTT == DTest & PV$Week== Wk, na.rm = TRUE)) {
  
  med<-PV %>%
    group_by(Category,Week,DTT) %>%
    summarize(across(ends_with("PV"), median))
  
  SPV<-df1%>%
    inner_join(med, by = c('Category', 'Week','DTT')) %>%
    mutate(across(matches("^DR0\\d+$"), ~.x + 
                    get(paste0(cur_column(), '_PV')),
                  .names = '{col}_{col}_PV')) %>%
    select(date1:Category, DR01_DR01_PV:last_col())
  
  SPV <- SPV %>%
    filter(date2 == dmda, Category == CategoryChosse, DTT==DTest)  
  
} 

else if(!(any(PV$DTT == DTest & PV$Week== Wk, na.rm = TRUE))) {
  
  med<-PV %>%
    group_by(Week) %>%
    summarize(across(ends_with("PV"), median))
  
  SPV<-df1%>%
    inner_join(med, by = c('Week')) %>%
    mutate(across(matches("^DR0\\d+$"), ~.x + 
                    get(paste0(cur_column(), '_PV')),
                  .names = '{col}_{col}_PV')) %>%
    select(date1:Category, DR01_DR01_PV:last_col())
  
  SPV <- SPV %>%
    filter(date2 == dmda)  
  
} 

else {
  
  med<-PV %>%
    group_by(Category,Week) %>%
    summarize(across(ends_with("PV"), median))
  
  
  SPV <- df1%>%
    inner_join(med, by = c('Category', 'Week')) %>%
    mutate(across(matches("^DR0\\d+$"), ~.x + 
                    get(paste0(cur_column(), '_PV')),
                  .names = '{col}_{col}_PV')) %>%
    select(date1:Category, DR01_DR01_PV:last_col())
  
  SPV <- SPV %>%
    filter(date2 == dmda, Category == CategoryChosse)
}

【问题讨论】:

  • 请不要在您的问题中添加rm(list = ls()) 之类的代码。没有人愿意在尝试帮助并失去工作时意外运行它。
  • 错误是if(){} 结尾与else if{}else{} 之间的换行符。当通过 R 控制台运行行时,解释器会认为您在到达有效行结束时立即完成,这发生在 if() 语句的末尾,除非同一行上有 else。将} &lt;&lt;line break&gt;&gt; else { 更改为} else { &lt;&lt;linebreak&gt;&gt;,您的代码将运行良好。
  • 仅供参考(因为这让我很困惑),else 之前的换行符是可以的如果它在花括号内,就像在函数内定义。我曾经以为我在某个 R 包的代码中发现了一个错误,因为else 之前有一个换行符,但它在函数定义中,所以没关系。 (虽然我确实认为好的做法是编写无论是否在函数中都能正常工作的代码。)
  • 为了优化,它在您创建med 的第一条语句中,似乎唯一的区别是要分组的列。所以你可以隔离分组位,比如group_cols = if(any(PV$DTT == DTest &amp; PV$Week== Wk, na.rm = TRUE)) {c("Category", "Week")} else {"Category"},然后是group_by(across(all_of(group_cols))),以获得med的单一定义,并在连接中类似地使用group_cols变量。
  • 我不清楚最终的else{} 是否会运行?难道你基本上没有if(X) {...} else if(!X) {...} else{...}。但是X!X 总是为真,所以最后的else{} 是没有意义的。

标签: r


【解决方案1】:

清理您的代码,确保在前面的if()} 所在行包含else 语句。

精简,如果无法获得,请不要使用else。打电话

X <- any(PV$DTT == DTest & PV$Week== Wk, na.rm = TRUE)

XTRUEFALSE。然后您的代码将读取

if(X) {
  ...
} else if(!X) {
  ...
} else {
  ...
}

永远不会到达最终的else,因为X!X 将是真的。

您还可以通过使用变量来避免重复,例如,一目了然ifelse if 之间的区别是分组列和连接列。因此,与其重写代码块,不如让这些元素动态化。像这样的东西(未经测试):

group_cols <-
  if(any(PV$DTT == DTest & PV$Week== Wk, na.rm = TRUE)) {
    c("Category", "Week", "DTT")
  } else {
    "Category"
  } 

med <- PV %>%
  group_by(across(all_of(group_cols))) %>%
  summarize(across(ends_with("PV"), median))

SPV <- df1 %>%
  inner_join(med, by = group_cols) %>%
  mutate(across(matches("^DR0\\d+$"), ~.x + 
                    get(paste0(cur_column(), '_PV')),
                  .names = '{col}_{col}_PV')) %>%
  select(date1:Category, DR01_DR01_PV:last_col())

SPV <- SPV %>% filter(date2 == dmda)

if("Category" %in% group_cols) {
  SPV = SPV %>% filter(Category == CategoryChosse, DTT==DTest) 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2017-03-16
    相关资源
    最近更新 更多