Простой цикл if-else в R - PullRequest
       3

Простой цикл if-else в R

8 голосов
/ 18 января 2012

Может кто-нибудь сказать мне, что не так с этим циклом if-else в R? Я часто не могу заставить циклы if-else работать. Я получаю ошибку:

if(match('SubjResponse',names(data))==NA) {
    observed <- data$SubjResponse1
}
else {
    observed <- data$SubjResponse
}

Обратите внимание, что data - это фрейм данных.

Ошибка

Error in if (match("SubjResponse", names(data)) == NA) { : 
  missing value where TRUE/FALSE needed

Ответы [ 2 ]

7 голосов
/ 18 января 2012

Это не полный пример, поскольку у нас нет данных, но я вижу следующие проблемы:

  1. Вы не можете проверить на NA с ==, вам нужно is.na()
  2. Аналогично, вывод match() и друзей обычно проверяется на NULL или length()==0
  3. Я склонен писать } else { в одну строку.
2 голосов
/ 18 января 2012

Как заметил @DirkEddelbuettel, вы не можете протестировать NA таким образом.Но вы можете заставить match не возвращать NA:

Используя nomatch=0 и переставляя предложение if (поскольку 0 рассматривается как FALSE), код можно упростить.Кроме того, другой полезной идиомой кодирования является назначение результата предложения if, чтобы вы не могли набрать имя переменной в одной из ветвей ...

Поэтому я бы написал это так:

observed <- if(match('SubjResponse',names(data), nomatch=0)) {
    data$SubjResponse # match found
} else {
    data$SubjResponse1 # no match found
}

Кстати, если у вас "часто" возникают проблемы с if-else, вы должны знать о двух вещах:

  1. Объект для проверки не должен содержатьNA или NaN, или строка (символ режима) или какой-либо другой тип, который не может быть приведен к логическому значению.Числовое значение ОК: 0 - это FALSE, все остальное (кроме NA / NaN) равно TRUE.

  2. Длина объекта должна быть ровно 1 (скалярное значение).Это может быть длиннее, но тогда вы получите предупреждение.Если оно короче, вы получите ошибку.

Примеры:

len3 <- 1:3
if(len3) 'foo'  # WARNING: the condition has length > 1 and only the first element will be used

len0 <- numeric(0)
if(len0) 'foo'  # ERROR: argument is of length zero

badVec1 <- NA
if(badVec1) 'foo' # ERROR: missing value where TRUE/FALSE needed

badVec2 <- 'Hello'
if(badVec2) 'foo' # ERROR: argument is not interpretable as logical
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...