在if语句条件之后lapply需要boolean

时间:2014-03-02 22:46:52

标签: r function if-statement lapply

我是R.的新手。我写了一个适用于数字的函数,并希望将它应用于长度为400的数字。它是

 EGIDS.to.IUCN <- function(x){
   if(x==10){return(NA)} # 10 (Extinct)
   if(x==9){return(NA)} # 9 (Dormant)
   if(x==8.5){return(4)} # 8.5 (Nearly Extinct) → 4 (Critically endangered) 
   # 10 more similar lines here (no more NAs)
   else{stop}
 }  

我尝试使用lapply然后我得到了

> austroIUCN <- lapply(austroEGIDS, EGIDS.to.IUCN)
Error in if (x == 10) { : missing value where TRUE/FALSE needed

其中austroEGIDS是从0到10的400个数字的列表。我在这里完全迷失了。关闭if条件后为什么期望一个布尔值?

2 个答案:

答案 0 :(得分:2)

如果使用数字向量并使用向量化语句,效率会更高:

austroIUCN <- unlist(austroEGIDS)
austroIUCN[austroIUCN==10 | austroIUCN==9] <- NA
austroIUCN[austroIUCN==8.5] <- 4
...

每个语句都设置具有给定级别的所有条目。

答案 1 :(得分:1)

如果没有stop这应该有效,

EGIDS.to.IUCN <- function(x) {
    if (is.na(x)){ NA } else
        if (x == 10) { NA } else
            if (x == 9) { NA } else
                if(x == 8.5) { 4 } else
                    NA
}

或者更可读,更快,

EGIDS.to.IUCN <- function(x){
    switch (x, 'NA'=NA, '10'=NA, '9'=NA, '8.5'=4, NA)
}

austroEGIDS <- sample(seq(1, 10, .5), 400, replace = TRUE)
austroIUCN <- sapply(austroEGIDS, EGIDS.to.IUCN)
table(unlist(austroIUCN), useNA = "ifany")

austroIUCN
   4 <NA> 
  23  377 

或者,如果您希望它停止并在不匹配时抛出错误,

EGIDS.to.IUCN <- function(x){
    switch (x, 'NA'=NA, '10'=NA, '9'=NA, '8.5'=4, stop("Not a match!"))
}