【发布时间】:2022-01-24 03:54:45
【问题描述】:
查看代码,您会发现我使用了if、else if 和else 条件。请注意,对于这两个条件,一些代码非常相似,一般情况下,条件之间的变化如下:group_by 来自第一个 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)
}
【问题讨论】:
-
请不要在您的问题中添加
rm(list = ls())之类的代码。没有人愿意在尝试帮助并失去工作时意外运行它。 -
错误是
if(){}结尾与else if{}和else{}之间的换行符。当通过 R 控制台运行行时,解释器会认为您在到达有效行结束时立即完成,这发生在if()语句的末尾,除非同一行上有else。将} <<line break>> else {更改为} else { <<linebreak>>,您的代码将运行良好。 -
仅供参考(因为这让我很困惑),
else之前的换行符是可以的如果它在花括号内,就像在函数内定义。我曾经以为我在某个 R 包的代码中发现了一个错误,因为else之前有一个换行符,但它在函数定义中,所以没关系。 (虽然我确实认为好的做法是编写无论是否在函数中都能正常工作的代码。) -
为了优化,它在您创建
med的第一条语句中,似乎唯一的区别是要分组的列。所以你可以隔离分组位,比如group_cols = if(any(PV$DTT == DTest & 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