尽管看起来正确完成,ifelse()仍暂停执行

时间:2019-04-05 20:31:37

标签: r

免责声明:我正在尝试使其他人的代码对用户更友好,并且我对R还是很陌生,所以如果您看到我使用不匹配的编码约定,这就是原因。

我试图在脚本通过文件列表时将其状态写入终端,在将其用作模型输入之前检查以确保它们有效。因此,我需要将一个变量(文件名)和状态(“看起来不错”)传递给一个函数,该函数将它们串联起来并以绿色写入终端。当我像这样测试功能时,它会起作用:

say <- function(words){
  cat(green(words))
}

hi <- "Hello"

say(c(hi, "World!"))
# Hello World!

但是当我从需要从其调用的ifelse()中调用say()时,出现了无法解密的错误:

FileList = as.data.frame(list.files(path = "./R_ModelInputs_SecondaryData",
                                    pattern = ".tif$", all.files = FALSE,
                                    full.names = FALSE, recursive = FALSE,
                                    ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE))
names(FileList)=c("FileName")

for(NAME in FileList$FilName){
  data=raster(paste("./R_ModelInputs_SecondaryData/",NAME,sep=""))

  ifelse(nrow(data)!=1737,
         say(c(NAME, "has a problem"),
         ifelse(ncol(data)!=4008,
                say(c(NAME, "has a problem")),
                say(c(NAME, "looks good"))
         ))
}
# Goode_FireBrightness_80_10kMax_20002015.tif  looks goodError in ans[!test & ok] <- rep(no, length.out = length(ans))[!test &
# :
#  replacement has length zero
# Calls: ifelse -> ifelse
# In addition: Warning message:
# In rep(no, length.out = length(ans)) :
#   'x' is NULL so the result will be NULL
# Execution halted

我尝试过搜索该错误,但我想出的只是它似乎来自ifelse()调用。这对我来说没有任何意义,因为它编写的“看起来不错”的事实意味着它已成功浏览了两个ifelse()。我在for循环的顶部插入了一条print()语句,以确保它在我的for循环的第二次迭代中尝试评估ifelse()时不会引发错误,但事实并非如此。该print()语句仅打印一次。

2 个答案:

答案 0 :(得分:1)

要返回向量时,应使用

ifelse()。它期望返回一个与您的第一个参数相同长度的向量。您的say()函数正在从cat()返回值,而该值仅返回NULL。没有办法使NULL与测试条件的长度相同。这使ifelse丢掉了。

ifelse不应用于控制流逻辑。您应该在此处使用标准if/else来执行条件代码。

使用

if(nrow(data)!=1737) {
  say(c(NAME, "has a problem") 
} else if (ncol(data)!=4008) {
  say(c(NAME, "has a problem"))
} else {
  say(c(NAME, "looks good"))
}

答案 1 :(得分:0)

或者以这种更R-y的方式进行操作

ff <- list.files(path = ".", pattern = "\\.tif$", full=TRUE)
r <- lapply(ff, raster)
x <- t(sapply(r, dim))
good <- x[,1] == 1737 & x[,2] == 4008
# good
basename(ff)[good]
# problem
basename(ff)[!good]