From bill at insightful.com  Wed Jan  9 21:33:13 2008
From: bill at insightful.com (Bill Dunlap)
Date: Wed, 9 Jan 2008 12:33:13 -0800 (PST)
Subject: [Rd] read.table: aborting based on a time constraint
In-Reply-To: <d054d5fa0801091101p3a93cd2ey7df35352416d2e6f@mail.gmail.com>
References: <d054d5fa0801091101p3a93cd2ey7df35352416d2e6f@mail.gmail.com>
Message-ID: <Pine.GSO.4.56.0801091213240.17807@devsun3201.insightful.com>

On Wed, 9 Jan 2008, Derek Stephen Elmerick wrote:

> Hello ?
>
> I am trying to write code that will read in multiple datasets;
> however, I would like to skip any dataset where the read-in process
> takes longer than some fixed cutoff. A generic version of the function
> is the following:
>
> for(k in  1:number.of.datasets)
> {
>    X[k]=read.table(?)
> }
>
> The issue is that I cannot find a way to embed logic that will abort
> the read-in process of a specific dataset without manual intervention.
> I scanned the help manual and other postings, but no luck based on my
> search. Any thoughts?

A long time ago, for S, I write a timeout(expr, seconds)
function that would return the value of expr if it completed
before 'seconds' seconds went by but would throw an error
otherwise.  One could then use try(timeout(expr, seconds))
to catch the error.

It only worked on Unix, as it spawned another process that would send
an interrupt signal back to S after the allotted time.  If the
expression were evaluated before the interrupter process finished, then S
would kill the interrupter process.  It relied on S catching the interrupt
and turning it into an error condition.

Translated into R code (unix()->system(intern=T)),
this function would be

   timeout <- function(expr, seconds = 60) {
     killer.pid <- system(intern = TRUE, paste(" (sleep", seconds,
        " ; echo 'Timed out after",
        seconds, "seconds' 1>&2 ; kill -INT", Sys.getpid(),
        ")>/dev/null&\n echo $!"))
     on.exit(system(paste("kill", killer.pid, "> /dev/null 2>&1")))
     expr
   }

E.g.,

   > timeout(log(2), seconds=1)
   [1] 0.6931472
   > timeout(while(TRUE)log(2), seconds=1)
   Timed out after 1 seconds

   >  # you get the prompt back in 1 second

R's try() doesn't catch interrupts and I haven't studied
tryCatch enough to use it to catch the interrupt.

This is pretty ugly, but I was wondering if R had the
facilities to write such a timeout() function.
I used to use it to automate tests of infinite-loop bugs.

----------------------------------------------------------------------------
Bill Dunlap
Insightful Corporation
bill at insightful dot com
360-428-8146

 "All statements in this message represent the opinions of the author and do
 not necessarily reflect Insightful Corporation policy or position."



[Rd] read.table: aborting based on a time constraint
Bill Dunlap