Như @DirkEddelbuettel đã lưu ý, bạn không thể kiểm tra NA
theo cách đó. Nhưng bạn có thể làm cho match
không trở về NA
:
Bằng cách sử dụng nomatch=0
và đảo ngược mệnh đề if
(kể từ 0
được coi là FALSE
), các mã có thể được đơn giản hóa. Hơn nữa, một thành ngữ mã hóa hữu ích khác là gán kết quả của mệnh đề if, theo cách đó bạn sẽ không nhập sai tên biến tại một trong các nhánh ...
Vì vậy, tôi viết như sau:
observed <- if(match('SubjResponse',names(data), nomatch=0)) {
data$SubjResponse # match found
} else {
data$SubjResponse1 # no match found
}
bằng cách nếu bạn "thường xuyên" có vấn đề với if-else, bạn nên lưu ý hai điều:
Đối tượng để kiểm tra không được chứa NA hoặc NaN, hoặc là một chuỗi (chế độ ký tự) hoặc một số loại khác không thể bị ép buộc thành một giá trị logic. Số là OK: 0 là FALSE
bất kỳ thứ gì khác (nhưng NA/NaN) là TRUE
.
Độ dài của đối tượng phải chính xác 1 (giá trị vô hướng). Nó có thể lâu hơn, nhưng sau đó bạn sẽ nhận được cảnh báo. Nếu nó ngắn hơn, bạn sẽ gặp lỗi.
Ví dụ:
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
'match' sẽ * luôn * trả về một vector của chiều dài tương tự như các đối số đầu tiên ('x'). Vì vậy, trong trường hợp này, luôn luôn là một giá trị vô hướng. – Tommy
Vòng tròn 8.1.4 của 'The R Inferno' http://www.burns-stat.com/pages/Tutor/R_inferno.pdf –