从代码来看,我使用了if、else if和else条件。请注意,对于这两种条件,有些代码非常相似,通常情况下,这些条件之间的变化如下:group_by来自med,inner_join来自第一个SPV,filter来自第二个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)
}发布于 2021-12-23 04:25:44
清理您的代码,确保在与前面的else的}相同的行中包含if()语句。
精简,不要使用else,如果它是不可能得到。打电话
X <- any(PV$DTT == DTest & PV$Week== Wk, na.rm = TRUE)X要么是TRUE要么是FALSE。然后,您的代码将读取
if(X) {
...
} else if(!X) {
...
} else {
...
}最终的else永远不会到达,因为X或!X都是真的。
您还可以通过使用变量来避免重复,例如,乍一看,if和else 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)
}https://stackoverflow.com/questions/70457270
复制相似问题