2012-01-18 43 views
8

Ai đó có thể cho tôi biết điều gì sai với vòng lặp if-else này trong R? Tôi thường xuyên không thể có được nếu vòng khác để làm việc. Tôi gặp lỗi:Vòng lặp if-else đơn giản trong R

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

Lưu ý rằng data là một khung dữ liệu.

Lỗi này là

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

Trả lời

2

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:

  1. Đố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.

  2. Độ 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 
7

Đây không phải là một ví dụ đầy đủ như chúng ta không có dữ liệu nhưng tôi thấy những vấn đề:

  1. Bạn không thể thử nghiệm cho NA với ==, bạn cần is.na()
  2. Tương tự, đầu ra của match() và bạn bè thường được kiểm tra NULL hoặc length()==0
  3. Tôi có xu hướng viết } else { trên một dòng.
+0

'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

+0

Vòng tròn 8.1.4 của 'The R Inferno' http://www.burns-stat.com/pages/Tutor/R_inferno.pdf –

Các vấn đề liên quan