Как заметил @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, вы должны знать о двух вещах:
Объект для проверки не должен содержатьNA или NaN, или строка (символ режима) или какой-либо другой тип, который не может быть приведен к логическому значению.Числовое значение ОК: 0 - это FALSE
, все остальное (кроме NA / NaN) равно TRUE
.
Длина объекта должна быть ровно 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