R中的新编码 我希望使这个代码更有效,并避免使用eval(解析)。目前我正在创建大量的Value对象,我确信它们可以更好地放在矢量或矩阵中。
输入:用户定义日期YYYYMM;例如201712
iEval_YYYYMM <- '201712'
所需输出:2种格式类型(A,B);根据用户输入下降3年
Value Objects:
A.RP0Y0 = '01-Jan-17'
B.RP0Y0 = '2017-01'
A.RP0Y1 = '01-Jan-16
B.RP0Y1 = '2016-01'
...
A.RP1Y0 = '01-Dec-16'
B.RP1Y0 = '2016-12'
...
A.RP1Y3 = '01-Dec-14'
B.RP1Y3 = '2014-12'
我能够创建我喜欢的所有Value对象,但我知道这不是很好的代码,我想避免使用eval(解析)。 我目前的代码:
iEval_Dt <- ymd(paste(iEval_YYYYMM,'01',sep='')) #reformat user input to date
l.name = c('RP0','RP1') #lag name vector
l.val = c(0,1) #lag value (months) vector
rp = c('Y0','Y1','Y2') #Rolling period vector
i = 1
j = 1
for(i in 1:length(l.name)) {
for(j in 1:length(rp)) {
b <- paste(l.name[i],rp[j],sep='')
assign(b,iEval_Dt %m-% months(11 + l.val[i] + (j-1)*12)) #begin date of RP
assign(paste('A.',b,sep=''),format(eval(parse(text=b)),'%Y-%m')) #formatA
assign(paste('B.',b,sep=''),format(eval(parse(text=b)),'%d-%b-%y')) #formatB
}
}
有关如何使此代码更清晰的任何提示以及存储这么多值对象的更好方法将不胜感激!
谢谢。答案 0 :(得分:2)
这应该让你走上更好的道路。不要试图将所有内容存储在单独的对象中 - 这会导致您eval(parsing())
的名称与paste
组合在一起 - 这实际上很难处理。只需将所有内容放在数据框中:
library(lubridate)
start = ymd(20171201)
lags = 0:1
years = 0:2
results = expand.grid(lags = lags, years = years)
results$date = start - months(results$lags) - years(results$years)
results$A = format(results$date, "%d-%b-%y")
results$B = format(results$date, "%Y-%m")
results
# lags years date A B
# 1 0 0 2017-12-01 01-Dec-17 2017-12
# 2 1 0 2017-11-01 01-Nov-17 2017-11
# 3 0 1 2016-12-01 01-Dec-16 2016-12
# 4 1 1 2016-11-01 01-Nov-16 2016-11
# 5 0 2 2015-12-01 01-Dec-15 2015-12
# 6 1 2 2015-11-01 01-Nov-15 2015-11
现在,您可以使用更有意义的A.RP1Y0
,而不是神秘的with(results, A[lags == 1 & years == 0])
。如果您需要Y0
,Y1
等标签,paste
将它们添加到新列中!
我认为我没有精确复制你的逻辑,但你应该能够根据这个例子让它工作。
答案 1 :(得分:0)
我感兴趣的任何人或任何人提出建议的完整代码:
library(lubridate)
iEval_YYYYMM <- readline(prompt="Enter evaluation month YYYYMM: ")
lag <- c(0,1,3)
rp <- 0:2
tDates <- expand.grid(lag = lag, rp = rp)
tDates$ID <- paste('RP',tDates$lag,'Y',tDates$rp,sep = '')
tDates$sDt <- iEval_Dt - months(11 + tDates$lag + tDates$rp * 12)
tDates$eDt <- tDates$sDt + months(12) - days(1)
tDates$sDt.EQ <- format(tDates$sDt,'%Y-%m')
tDates$sDt.CQ <- format(tDates$sDt,'%d-%b-%y')
tDates$eDt.EQ <- format(tDates$eDt,'%Y-%m')
tDates$eDt.CQ <- format(tDates$eDt,'%d-%b-%y')
CQUpdate <- function(q) {
i <- 1
j <- 1
tmp <- q
for(i in 1:length(lag)) {
for(j in 1:length(rp)) {
# replace start dates for each rolling period
find <- paste('<<s',tDates$ID[tDates$lag == lag[i] & tDates$rp ==
rp[j]],'>>',sep='')
replace <- tDates$sDt.CQ[tDates$lag == lag[i] & tDates$rp == rp[j]]
tmp <- gsub(find,replace,tmp,fixed=TRUE)
# replace end dates for each rolling period
find <- paste('<<e',tDates$ID[tDates$lag == lag[i] & tDates$rp ==
rp[j]],'>>',sep='')
replace <- tDates$eDt.CQ[tDates$lag == lag[i] & tDates$rp == rp[j]]
tmp <- gsub(find,replace,tmp,fixed=TRUE)
# replace date for End of Month date of Evaluation Month (DD/MM/YYYY)
tmp <- gsub('<<EOM>>',format(iEval_Dt + months(1) -
days(1),'%d/%m/%Y'),tmp,fixed=TRUE)
}
}
tmp
}
#subtle change from prior - replaces with EQ formats
EQUpdate <- function(q) {
i <- 1
j <- 1
tmp <- q
for(i in 1:length(lag)) {
for(j in 1:length(rp)) {
# replace start dates for each rolling period
find <- paste('<<s',tDates$ID[tDates$lag == lag[i] & tDates$rp ==
rp[j]],'>>',sep='')
replace <- tDates$sDt.EQ[tDates$lag == lag[i] & tDates$rp == rp[j]]
tmp <- gsub(find,replace,tmp,fixed=TRUE)
# replace end dates for each rolling period
find <- paste('<<e',tDates$ID[tDates$lag == lag[i] & tDates$rp ==
rp[j]],'>>',sep='')
replace <- tDates$eDt.EQ[tDates$lag == lag[i] & tDates$rp == rp[j]]
tmp <- gsub(find,replace,tmp,fixed=TRUE)
# replace Eval month year and month
tmp <- gsub('<<YYYY>>',substr(iEval_YYYYMM,1,4),tmp,fixed=TRUE)
tmp <- gsub('<<MM>>',substr(iEval_YYYYMM,5,6),tmp,fixed=TRUE)
}
}
tmp
}