ifelse对NA值有什么作用?

时间:2014-02-11 12:53:42

标签: r if-statement na

我有代码可以做我想要的。但是,我非常想了解它为什么会以某种方式工作而不是另一种方式。

我想有条件地将新值放入新列中,并编写以下代码:

test <- data.frame(Usual=c(1:3,NA,NA,4,5,7,15))

test$Active1 <- NA

test$Active1 <- ifelse(test[,"Usual"]==1|test[,"Usual"]==2|test[,"Usual"]==3,1,
                       ifelse(test[,"Usual"]==7,2,
                              ifelse(test[,"Usual"]==4|test[,"Usual"]==5|test[,"Usual"]==6|test[,"Usual"]==7,3,
                                     ifelse(is.na(test[,"Usual"]),"ROAR",":("))))

我在最后为is.na添加了额外的条件,因为如果我不这样做,我不确定是否会感到困惑。但它没有用“ROAR”取代NAs - 为什么?

如果我把is.na的条件放在ifelse的前面,那就完成了我的预期:

test$Active2 <- NA
  test$Active2 <- ifelse(is.na(test[,"Usual"]),"ROAR",
                         ifelse(test[,"Usual"]==7,2,
                                ifelse(test[,"Usual"]==4|test[,"Usual"]==5|test[,"Usual"]==6|test[,"Usual"]==7,3,
                                       ifelse(test[,"Usual"]==1|test[,"Usual"]==2|test[,"Usual"]==3,1,":("))))

为什么它放在ifelse中会有所不同? (我甚至不需要使用ifelse,但我很好奇它是否看起来更整洁..)

2 个答案:

答案 0 :(得分:1)

从帮助页面:

  当且仅当测试的任何元素为真时,才会评估

是,并且类似于否。

在您的第一个示例中,ifelse(is.na())永远不会针对NA行进行评估,因为它无法在第一个ifelse条件下进行评估。

答案 1 :(得分:0)

只需在R控制台中输入ifelse即可轻松回答这类问题,并会显示所使用的代码。学习代码将告诉您它对NA的作用。

R > ifelse
function (test, yes, no) 
{
    if (is.atomic(test)) {
        if (typeof(test) != "logical") 
            storage.mode(test) <- "logical"
        if (length(test) == 1 && is.null(attributes(test))) {
            if (is.na(test)) 
                return(NA)
            else if (test) {
                if (length(yes) == 1 && is.null(attributes(yes))) 
                  return(yes)
            }
            else if (length(no) == 1 && is.null(attributes(no))) 
                return(no)
        }
    }
    else test <- if (isS4(test)) 
        as(test, "logical")
    else as.logical(test)
    ans <- test
    ok <- !(nas <- is.na(test))
    if (any(test[ok])) 
        ans[test & ok] <- rep(yes, length.out = length(ans))[test & 
            ok]
    if (any(!test[ok])) 
        ans[!test & ok] <- rep(no, length.out = length(ans))[!test & 
            ok]
    ans[nas] <- NA
    ans
}
<bytecode: 0x1018abad0>
<environment: namespace:base>