如果错误,则在R中的for循环中进行下一次迭代

jm2pwxwz  于 2023-06-03  发布在  其他
关注(0)|答案(2)|浏览(187)

我正在寻找一种简单的方法,如果for循环中的操作出错,可以在R中的for循环中进行下一次迭代。
我在下面重新创建了一个简单的案例:

for(i in c(1, 3)) {
  test <- try(i+1, silent=TRUE)
  calc <- if(class(test) %in% 'try-error') {next} else {i+1}
  print(calc)
}

这正确地给出了以下计算值。

[1] 2
[1] 4

然而,一旦我改变i中的向量以包含非数字值:

for(i in c(1, "a", 3)) {
  test <- try(i+1, silent=TRUE)
  calc <- if(class(test) %in% 'try-error') {next} else {i+1}
  print(calc)
}

这个for循环不起作用。我希望得到与上面相同的calc值,其中vector排除了i中的非数值。
我尝试使用tryCatch如下:

for(i in c(1, "a", 3)) {
  calc <- tryCatch({i+1}, error = function(e) {next})
  print(calc)
}

但是,我得到以下错误:

Error in value[[3L]](cond) : no loop for break/next, jumping to top level

有人能帮助我理解如何在R中使用for循环来实现这一点吗?

n9vozmp4

n9vozmp41#

正如Dason所指出的,原子向量确实不是存储混合数据类型的最佳方式。名单就是为了这个。考虑以下几点:

l = list(1, "sunflower", 3)

for(i in seq_along(l)) {
   this.e = l[[i]]
   test <- try(this.e + 1, silent=TRUE)
   calc <- if(class(test) %in% 'try-error') {next} else {this.e + 1}
   print(calc)
}

[1] 2
[1] 4

换句话说,你以前的循环“工作”了。它只是 * 总是 * 失败,并进入下一次迭代。

u5rb5r59

u5rb5r592#

这里有一个使用“purr”包的解决方案,可能会有所帮助。它遍历你的列表或向量,并返回会导致错误的元素

#Wrap the function you want to use in the adverb "safely" 
safetest <- safely(function(x){ifelse(is.na(as.numeric(x)),
                                  x+1,
                                  as.numeric(x)+1)})

myvect<-c(1,"crumbs",3) #change to list if you want a list

#Use the safe version to find where the errors occur
check <- myvect  %>% 
  map(safetest) %>%
  transpose %>% .$result %>% 
  map_lgl(is_null)

myvect[check]

#This returns the results that did not through an error
#first remove NULL elements then flatten to double.
#The two flatten expresiion can be replaced by a single unlist
myvect  %>% 
  map(safetest) %>%
  transpose %>% .$result %>% 
  flatten()%>%flatten_dbl()

参见https://blog.rstudio.org/2016/01/06/purrr-0-2-0/的原始示例。

相关问题