ifelse () останавливает выполнение, несмотря на правильное завершение - PullRequest
0 голосов
/ 05 апреля 2019

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

Я пытаюсь записать состояние моего скрипта в терминал, когда он просматривает список файлов, проверяя, чтобы они были действительными, прежде чем использовать их в качестве входных данных для модели. Поэтому мне нужно передать переменную (имя файла) и состояние («хорошо выглядит») функции, которая объединит их и запишет в терминал зеленым цветом. Когда я тестирую эту функцию, она работает:

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

hi <- "Hello"

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

Но когда я вызываю say () из ifelse (), из которого мне нужно его вызвать, я получаю ошибку, которую не могу расшифровать:

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 (). Я вставил оператор print () в верхней части цикла for, чтобы он не выдавал ошибку, когда пытался вычислить ifelse () во второй итерации цикла for, но это не то, чем он является, поскольку этот оператор print () печатается только один раз.

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

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"))
}
0 голосов
/ 06 апреля 2019

Или сделайте это более R-у, как это

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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...