прерывание цикла for при запуске функции внутри цикла for в R - PullRequest
8 голосов
/ 25 марта 2010

Предположим, у вас есть следующая функция foo. Когда я запускаю цикл for, я бы хотел пропустить остаток от foo, когда foo первоначально возвращает значение 0. Однако break не работает, когда находится внутри функции.

Как сейчас написано, я получаю сообщение об ошибке, no loop to break from, jumping to top level.

Есть предложения?

foo <- function(x) {
    y <- x-2
    if (y==0) {break} # how do I tell the for loop to skip this
    z <- y + 100
    z
}


for (i in 1:3) {
    print(foo(i))
}

Ответы [ 5 ]

7 голосов
/ 25 марта 2010

По общему признанию мои знания R редки, и это сухое кодирование, но что-то вроде следующего должно работать:

foo <- function(x) {
    y <- x-2
    if (y==0) {return(NULL)} # return NULL then check for it
    z <- y + 100
    z
}

for (i in 1:3) {
    j <- foo(i)
    if(is.null(j)) {break}
    print(j)
}

Редактировать: обновлена ​​нулевая проверка на потомство

4 голосов
/ 25 марта 2010

Разрешено ли нам быть немного более креативным? Не могли бы вы изменить свою проблему, чтобы воспользоваться преимуществами следующего подхода, где операция основана на векторах?

x <- 1:3  
y <- x[x-2 < 0] - 2 + 100 # I'm leaving the "- 2" separate to highlight the parallel to your code  
y  

Если, однако, в основе вопроса лежит более глубокая форма, и нам нужно сейчас следовать этой схеме, возможно, немного ее подправить ...

foo <- function(x) {
  y <- x - 2
  if (y != 0) {
    z <- y + 100
    z
  } # else implicitly return value is NULL
}

for (i in 1:3) {
  if (is.numeric(result <- foo(i))) {
    print(result)
  } else {
    break 
  }
}
4 голосов
/ 25 марта 2010

В качестве практики кодирования не делайте этого. Наличие функции, которая может использоваться только внутри определенного цикла, не очень хорошая идея. В интересах образования вы можете оценить «разрыв» в родительской среде.

foo <- function(x) {
    y <- x-2
    if (y==0) {eval.parent(parse(text="break"),1)} 
    z <- y + 100
    z
}



for (i in 0:3) {
    print(foo(i))
}
2 голосов
/ 25 марта 2010

Альтернативный способ - выдать ошибку и перехватить ее с помощью try, например:

foo <- function(x) {
    y <- x-2
    if (y==0) {stop("y==0")} 
    z <- y + 100
    z
}

try(for (i in 0:5) {
       print(foo(i))
}, silent=TRUE)

## or use tryCatch:
for (i in 0:5) {
   bar <- tryCatch(foo(i),error=function(e) NA)
   if(is.na(bar)){ break } else { print(bar) }
}
0 голосов
/ 25 марта 2010

Понятия не имею, как работает r, но мне показался интересным вопрос, потому что я мог найти синтаксис нового языка, поэтому извините за мой ответ, если он полностью неверен:)

foo <- function(x) { 
    y <- x-2 
    if (y!=0) z <- NULL else z <- y + 100 
    z 
}


for (i in 1:3)
{ 
    a <- foo(i)
    if (a == NULL) {next}
    print(a)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...