2011-12-28 18 views
5

Quiero aplicar una función ("foo" para esta explicación) para transformar un vector de datos en otro valor. Esta función toma los datos como una entrada y necesita enviar formularios a páginas web. A veces, esto sucede rápidamente, y otras veces, puede pasar mucho tiempo. Me gustaría ejecutar el bucle for (o función de aplicación equivalente) de una manera que se salte los elementos que tardan demasiado. He tratado de limitar el tiempo que el bucle se ejecuta antes de pasar al lado de 5 segundos utilizando la siguiente:Limitar el tiempo que una función procesa en una R para el ciclo

pb <- txtProgressBar(min = 1, max = 100, style = 3) 
storage <- matrix(nrow = sample.length, ncol = 2) 

for(i in 1:100){ 
    s <- Sys.time() 
    storage[i,] <- try(foo(data.vec[i]), TRUE) 
    if (Sys.time() - s >5) {next} 
    # update progress bar 
    setTxtProgressBar(pb, i) 
} 
close(pb) 

Creo que no debía haber comprensión de cómo se aplica la condición de 'siguiente' en un bucle. han buscado para encontrar una explicación más clara, pero no han tenido suerte aquí.

+0

Su foo() no vuelve a Sys.time antes de finalizar. Si desea obtener el salto, debe agregar un código similar en la función foo; o ejecuta foo en un hilo separado, pero eso no es fácil. –

+0

El ejemplo 'evalWithTimeout' es el camino a seguir. De lo contrario: ¿quizás la función real que está utilizando para llamar a las páginas web (o lo que sea) tiene un argumento de tiempo de espera incorporado? Vale la pena profundizar en la documentación si aún no lo has hecho. –

Respuesta

9

evalWithTimeout() del paquete R.utils, en concierto con tryCatch(), podría proporcionar una solución más limpia.

Por ejemplo:

require(R.utils) 

for(i in 1:5) { 
    tryCatch(
     expr = { 
      evalWithTimeout({Sys.sleep(i); cat(i, "\n")}, 
          timeout = 3.1) 
      }, 
     TimeoutException = function(ex) cat("Timeout. Skipping.\n") 
    ) 
} 

# 1 
# 2 
# 3 
# Timeout. Skipping. 
# Timeout. Skipping. 

En el ejemplo artificial arriba:

  • El primer argumento de evalWithTimeout() contiene el código para ser evaluadas dentro de cada bucle.

  • El argumento timeout en evalWithTimeout() establece el límite de tiempo en segundos.

  • El argumento TimeoutException al tryCatch() toma una función que se debe ejecutar cuando se agota el tiempo de una iteración del ciclo.

Cuestiones relacionadas