Break / exit from nested blocks in R without printing error messages - r

I've been writing an R script that would simulate outbound phone calls from a call center to demonstrate the rules ( if the call counts exceeds 5 OR if the call is a success OR a call back request is set then the code should exit). If I use break statement, I'm not getting the desired result, as a workaround I'm using the stop function. Is there a way to print a message and stop executing a function without throwing an Error ?
This is my code:
dial <- function(callcount = 1)
{
maxcalls <- 5
# Possible Outcomes
outcomes <- c("RPCON","WPCON","CBLTR")
# Probaility Vector for results:
pvector <- c(1,1,1)
repeat{
if(callcount == 5){
stop("5 attempts reached, closing record for the day")
}
res <- sample(outcomes, 1, prob=pvector, rep = TRUE)
print(paste0("Attempt ",callcount))
if(res == "RPCON" & callcount <= 5){
print("Call Successful")
stop(simpleError("Ended"))
}else if(res == "WPCON" & callcount <= 5){
print("Wrong Party!, Trying alternate number...")
callcount <- callcount + 1
dial(callcount)
}else if(res == "CBLTR" & callcount <= 5){
print("Call back request set by agent")
stop("Ended")
}
}# End of REPEAT loop
}# End of function
Any help is appreciated.

I would suggest to use a While loop with a boolean to check if you want to continue to loop :
dial <- function(callcount = 1)
{
maxcalls <- 5
# Possible Outcomes
outcomes <- c("RPCON","WPCON","CBLTR")
# Probaility Vector for results:
pvector <- c(1,1,1)
endLoop <- FALSE
while(callcount <=5 & endLoop == FALSE ){
if(callcount == 5){
stop("5 attempts reached, closing record for the day")
}
res <- sample(outcomes, 1, prob=pvector, rep = TRUE)
print(paste0("Attempt ",callcount))
if(res == "RPCON" & callcount <= 5){
print("Call Successful")
endLoop <- TRUE
}else if(res == "WPCON" & callcount <= 5){
print("Wrong Party!, Trying alternate number...")
callcount <- callcount + 1
dial(callcount)
}else if(res == "CBLTR" & callcount <= 5){
print("Call back request set by agent")
endLoop <- TRUE
}
}# End of REPEAT loop
}# End of function
Hope this helps.

Related

If loop - Argument is of length zero - error

I do have the following code for a loop, which basically only updates the column "decay rate" based on whether or not the column "RPK_cap" is higher than a certain threshold which is exogenously given(in scenario 1 it is 1200, in Scenario 2 it is 1300 etc). If that is the case than I want to decrease the decay rate by multiplying it my 0.9. This is done for all countries (column: iso) and years(column: year) which are in the data.table. When I am using scenario 1 data the column "RPK_cap" will be filled with scenario 1 data and if I choose scenario 2 the column "RPK_cap" will be filled with scenario 2 data respectively.
And my problem is the following:
This loop works ONLY for scenario 1.
If I am using scenario 2 I get the error message:
"Error in if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == :
argument is of length zero"
I really tried a lot and I just donĀ“t know what the problem is here. Does anyone know what the problem is?
This is the data.table
data.table_example
if (scenario == "1") {
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1200) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.90
}
}
}
} else if (scenario == "2"){
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1300) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.95
}
}
}
} else if (scenario == "3"){
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1400) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.95
}
}
}
} else if (scenario == "4"){
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1500) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.95
}
}
}
} else if (scenario == "5"){
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1600) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.99
}
}
}
}else{}
It's hard to answer in specifics because we cannot see your data.
But the error you see
"Error in if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == : argument is of length zero"
is because price_el_int_aviation_RPK$iso is of length zero - it's a vector without anything in it!
Here's a minimal example of the problem
# Create a vector of length zero
a <- c()
# Prove it's length is zero
length(a)
# [1] 0
# This is a minimal example of what's going wrong with scenario 2 in your script
if(a == 2) { print("it works") }
Error in if (a == 2) if (a == 2) { : argument is of length zero

If & ifelse statement in R

As the new user in R, I met few problems when I tried to evaluate a.
Code:
// time2 are numbers //
a = d3$Time2
b = c(...)
for (i in 1:65){
for (j in 1:1762){
if( (a[j]>=1474161415+900*(i-1))&(a[j]<1474161415+900*i) ){ a[j] = b[j] }
}
}
Results:
Error in if ((a[j] >= 1474161415 + 900 * (i - 1)) & (a[j] < 1474161415 + :
missing value where TRUE/FALSE needed
Also I have tried:
ifelse( ((a[j]>=1474161415+900*(i-1)) & (a[j]<1474161415+900*i)) , a[j]=b[j])
Results:
-unexpected '=' in -ifelse( ((a[j]-=1474161415+900-(i-1)) &
(a[j]-1474161415+900-i)) , a[j]=--

Getting "unexpected numeric constant" in code

I am trying to run my code but get the following error:
Error: unexpected numeric constant in: "
if((final.string[1+loop.check]) !=
(final.string[string.length-loop.check])){
return FALSE"
My code is as below:
inputString = "aabb"
string.length <- nchar(inputString)
compare.list <- strsplit(inputString,"")
final.string <- unlist(compare.list)
loop.check <- 0L
if(string.length %% 2 == 0){
loop.stop <- string.length/2
}
if(string.length %% 2 == 1){
loop.stop <- (string.length -1) / 2
}
while (loop.check<=loop.stop){
if((final.string[1+loop.check]) != (final.string[string.length-loop.check])){
return FALSE
break
}
else{
loop.check <- loop.check + 1
}
}
if(loop.check-1==loop.stop){
return TRUE
}
If I run just the (final.string[1+loop.check]) != (final.string[string.length-loop.check]) portion then the console returns FALSE so the code for the if statement condition seems to be working. However, when attempting to run the whole script I get the above error.

Change winddirection degrees to char in R

I have read in a csv file about weather on days. One of the variables is called winddirection (windrichting) but it is given in degrees and 0 and 990 have special meaning.
I want to change the numbers to North/South/West/East but when I used the replace function it changed the datatype of the whole vector to char which prevented my next replace with a range to work. So now I ended up with an if/else if/else statement but I can't get it to work. Also I get an error condition has length > 1. Can anyone help me get this to work so I have the ranges 45-135 to east, 135-225 south, etc.
here is my code where mydata$DD is the variable for wind direction with over 2000 values.
windrichting <- mydata$DD
windrichting <- if (windrichting == 990 ){
windrichting == "Veranderlijk"
} else if (windrichting>45 && windrichting<=135){
windrichting == "Oost"
} else if (windrichting>135 && windrichting<=225){
windrichting == "Zuid"
} else if (windrichting>225 && windrichting <=315){
windrichting == "West"
} else if (windrichting ==0){
windrichting == "Windstil"
} else windrichting == "Noord"
Perhaps something along the lines of this?
tmp <- round((windrichting + 45) / 90) %% 8
tmp[windrichting == 990] <- 8
tmp <- factor(tmp, levels = 0:9, labels = c("Noord", "Oost", "Zuid", "West", "Veranderlijk", "Windstil"))
tmp[windrichting == 0] <- "Windstil"
windrichting <- tmp
You can do this using an *apply function.
windrichting_text <- unlist(lapply(windrichting, function (x) {
if (x == 990) {
return("Veranderlijk")
} else if {
....
} else {
return ("Noord")
})
This applies the function defined to all elements in the list.

R: data.frame too slow in loops?

I'm backtesting trading strategies with R. This is at the moment my code.
- MergedSet$FXCloseRate contains the closing price for a certain currency pair
- MergedSet$RiskMA is the moving average of a certain risk index
- the rest should be clear
This formula at the Moment is not really fast over 11'000 entries. Why? Are data frames too slow? Where can I optimise here?
############
# STRATEGY #
############
#Null out trades and position
MergedSet$Trade <- 0
MergedSet$Position<-0
MergedSet$DailyReturn<-0
MergedSet$CumulativeReturn<-0
MergedSet$Investment<-0
MergedSet$CumulativeReturn[1:MAPeriod] <- 1
MergedSet$Investment[1:MAPeriod] <- InitialInvestment
#Strategy
n<-nrow(MergedSet)
for(i in seq(MAPeriod+1,n)){
#Updating the position
if(MergedSet$RiskMA[i] <= ParamDwn && MergedSet$RiskMA[i-1] > ParamDwn){
#sell signal, so short if no or long position active otherwise do nothing
if(MergedSet$Position[i-1] == 0 || MergedSet$Position[i-1] == 1){
MergedSet$Position[i] = -1
MergedSet$Trade[i] = 1
}
} else if(MergedSet$RiskMA[i] >= ParamUp && MergedSet$RiskMA[i-1] < ParamUp){
#buy signal, go long if no or short position active, otherwise do nothing
if(MergedSet$Position[i-1] == 0 || MergedSet$Position[i-1] == -1){
MergedSet$Position[i] = 1
MergedSet$Trade[i] = 1
}
} else {
MergedSet$Position[i] = MergedSet$Position[i-1]
}
#Return calculation
if(MergedSet$Position[i] == 1){
#long
MergedSet$DailyReturn[i] = MergedSet$FXCloseRate[i]/MergedSet$FXCloseRate[i-1]-1
} else if(MergedSet$Position[i] == -1){
#short
MergedSet$DailyReturn[i] = MergedSet$FXCloseRate[i-1]/MergedSet$FXCloseRate[i]-1
}
}

Resources