R中的简单if-else循环

Cod*_*Guy 8 if-statement r

有人能告诉我这个在R中的if-else循环有什么问题吗?我经常无法使if-else循环工作.我收到一个错误:

if(match('SubjResponse',names(data))==NA) {
    observed <- data$SubjResponse1
}
else {
    observed <- data$SubjResponse
}
Run Code Online (Sandbox Code Playgroud)

请注意,这data是一个数据框.

错误是

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

Dir*_*tel 7

这不是一个完整的例子,因为我们没有数据,但我看到了这些问题:

  1. 不能测试NA==,你需要is.na()
  2. 同样,match()和朋友的输出通常会测试为NULL或length()==0
  3. 我倾向于写} else {一行.


Tom*_*mmy 2

正如@DirkEddelbuettel 指出的,你不能NA这样测试。但你可以match不返回NA

通过使用nomatch=0和反转该if子句(since0被视为FALSE),可以简化代码。此外,另一个有用的编码习惯是分配 if 子句的结果,这样您就不会在其中一个分支中输错变量名称......

所以我会这样写:

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

顺便说一句,如果您“经常”遇到 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
Run Code Online (Sandbox Code Playgroud)