Breaking Loop When "Warnings()" Appear in R

Breaking loop when warnings() appear in R

You can turn warnings into errors with:

options(warn=2)

Unlike warnings, errors will interrupt the loop. Nicely, R will also report to you that these particular errors were converted from warnings.

j <- function() {
for (i in 1:3) {
cat(i, "\n")
as.numeric(c("1", "NA"))
}}

# warn = 0 (default) -- warnings as warnings!
j()
# 1
# 2
# 3
# Warning messages:
# 1: NAs introduced by coercion
# 2: NAs introduced by coercion
# 3: NAs introduced by coercion

# warn = 2 -- warnings as errors
options(warn=2)
j()
# 1
# Error: (converted from warning) NAs introduced by coercion

When warnings occur in a loop in R, is it possible to report and extract which iteration it occurs in?

Use tryCatch

for(i in 1:100){ 
set.seed(i)
x = c(runif(100, min=-3, max=3), 200)
y = rbinom(101, size=1, prob=1/(1+exp(-x)))
tryCatch({m <- glm(y~x, family=binomial)}, warning=function(w) print(i))
}

How to detect warnings in R and have a while loop run on a function as along as warnings are outputted?

You can use tryCatch() function to catch errors and warnings and adjust your workflow based on the result, i.e:

x = -3.5

repeat{

x <- x + 0.6
print( paste("Current value of x is", x) )

result <- tryCatch( log( x ),
error = function(e) e,
warning = function(w) w )

if (inherits(result,"warning")) next # For warnings - continue the next iteration
if (inherits(result,"error")) stop( result ) # For errors - stop


print( paste0(" log(",x,")=", result))
break
}

# [1] "Current value of x is -2.9"
# [1] "Current value of x is -2.3"
# [1] "Current value of x is -1.7"
# [1] "Current value of x is -1.1"
# [1] "Current value of x is -0.5"
# [1] "Current value of x is 0.1"
# [1] " log(0.1)=-2.30258509299404"

However, be very careful with repeat and while loops as you might end up creating an infinite loop. It might be a good idea to check how many iterations the loop has executed and abort it in case there have been too many iterations:

x = -3.5
iter <- 0

while (iter < 100) {

x <- x + 0.6
iter <- iter + 1

print( paste("Current value of x is", x) )

result <- tryCatch( log( x ),
error = function(e) e,
warning = function(w) w )

if (inherits(result,"warning")) next # For warnings - continue the next iteration
if (inherits(result,"error")) stop( result ) # For errors - stop


print( paste0(" log(",x,")=", result))
break
}

R : Returning a value from loop when manually stopping it

I come across this problem often in webscraping. The key is to store the intermediate results in an environment where they are accessible if your function throws an error. The obvious place is the global environment, but this depends on how you are using your function. If it is part of a package, then you don't want to write to the global workspace. In that case you can have a "storage" environment as part of the package.

Perhaps the neatest way to do this is to delete the intermediate object after the loop is complete, so it will only ever be visible / accessible if the loop throws an error.

Here is a function that demonstrates the principle:

write_data_frames <- function(n)
{
if(!exists("temporary", .GlobalEnv))
{
assign("temporary", list(), envir = globalenv())
i <- 1
}
else
{
i <- length(.GlobalEnv$temporary) + 1
}

while(i <= n)
{
# This is the block where you do your web scraping and store the result
.GlobalEnv$temporary[[i]] <- data.frame(var1 = rnorm(1), var2 = runif(1))

# We'll create an error when i == 4
if(i == 4) stop("Something broke!")
i <- i + 1
}
result <- do.call(rbind, temporary)
rm("temporary", envir = globalenv())
return(result)
}

Now, this should return a nice data frame if I ask it for 3 rows:

write_data_frames(3)
#> var1 var2
#> 1 -1.6428100 0.1976913
#> 2 0.7136643 0.9684348
#> 3 -0.4845004 0.0294557

And it hasn't left anything in our global workspace:

ls()
#> [1] "write_data_frames"

But suppose I ask for ten rows: here, it will throw an error on the fourth loop:

write_data_frames(10)
#> Error in write_data_frames(10) : Something broke!

However, this time, the object temporary is available to me:

ls()
#> [1] "temporary" "write_data_frames"

temporary
#> [[1]]
#> var1 var2
#> 1 -1.46648 0.1748874
#>
#> [[2]]
#> var1 var2
#> 1 -0.03855686 0.5772731
#>
#> [[3]]
#> var1 var2
#> 1 0.8228591 0.4115181
#>
#> [[4]]
#> var1 var2
#> 1 0.9183934 0.2732575

Even better, my function is designed to just carry on from where it left off, so if I once again do

write_data_frames(10)
#> var1 var2
#> 1 -1.46647987 0.1748874
#> 2 -0.03855686 0.5772731
#> 3 0.82285907 0.4115181
#> 4 0.91839339 0.2732575
#> 5 0.54850658 0.9946303
#> 6 -1.39917426 0.9948544
#> 7 0.39525152 0.9234611
#> 8 -1.05899076 0.6226182
#> 9 -2.03137464 0.1218762
#> 10 0.24880216 0.6631982

The function has started again from position 5 without any modification. And now, when we check our global workspace, there's nothing left:

ls()
#> [1] "write_data_frames"

How to avoid warning of Unreachable code

Your code is currently broken, basically. You're really never going to execute m = m.NextMatch(), so why have it?

I think you want:

Regex r = new Regex(@"~(\w*[a-zA-Z0-9$£~%]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled);

Match m = r.Match(expression);
string currency = m.Success ? m.Groups[1].Value : "";

Personally I think this is rather clearer, in terms of what the final version of "currency" is.



Related Topics



Leave a reply



Submit