如何在ifelse中包含NA?

问题描述 投票:25回答:5

我正在尝试基于其他列的值的逻辑语句创建列ID。例如,在以下数据框中

test <- structure(list(time = c(10L, 20L, NA, 30L), type = structure(c(1L, 
2L, 3L, NA), .Label = c("A", "B", "C"), class = "factor"), ID = c(NA, 
"1", NA, NA)), .Names = c("time", "type", "ID"), row.names = c(NA, 
-4L), class = "data.frame")

看起来像

    time    type
1   10      A
2   20      B
3   NA      C
4   30      NA

我想为所有不是IDtime和所有不是NAtype制作一个新的列A,其值为1。我使用以下代码:

test$ID <- ifelse(is.na(test$time) | test$type == "A", NA, "1")

这给出了结果

    time    type    ID
1   10      A       NA
2   20      B       1
3   NA      C       NA
4   30      NA      NA

但是,此代码忽略NA列中的type,导致NA列中的ID值。我需要这个值为1,所以我需要的解决方案应该给:

    time    type    ID
1   10      A       NA
2   20      B       1
3   NA      C       NA
4   30      NA      1

有人能告诉我怎么做这个吗?如果我能以某种方式改变is.na(test$type)的结果以返回FALSE而不是TRUE,我可以使用我现有的代码,但我不知道该怎么做。或者,我现有代码的结构可能需要完全改变吗?我感谢任何帮助!

r if-statement
5个回答
30
投票

你不能真正比较NA与另一个值,所以使用==将无法正常工作。考虑以下:

NA == NA
# [1] NA

你可以改变从==%in%的比较:

ifelse(is.na(test$time) | test$type %in% "A", NA, "1")
# [1] NA  "1" NA  "1"

关于你的其他问题,

如果我能以某种方式改变is.na(test$type)的结果以返回FALSE而不是TRUE,我可以使用我现有的代码,但我不知道该怎么做。

只需使用!否定结果:

!is.na(test$time)
# [1]  TRUE  TRUE FALSE  TRUE

5
投票

@AnandaMahto解决了为什么你得到这些结果并提供了最清楚的方法来获得你想要的东西。但另一种选择是使用identical而不是==

test$ID <- ifelse(is.na(test$time) | sapply(as.character(test$type), identical, "A"), NA, "1")

或者使用isTRUE

test$ID <- ifelse(is.na(test$time) | Vectorize(isTRUE)(test$type == "A"), NA, "1")

3
投票

听起来你想要ifelse语句在比较中将NA值解释为FALSE而不是NA。我使用以下函数来处理这种情况,所以我不必持续处理NA情况:

falseifNA <- function(x){
  ifelse(is.na(x), FALSE, x)
}

ifelse2 <- function(x, a, b){
  ifelse(falseifNA(x), a, b)
}

您还可以将这些功能组合成一个以提高效率。因此,要返回您想要的结果,您可以使用:

test$ID <- ifelse2(is.na(test$time) | test$type == "A", NA, "1")

0
投票

所以,我听说这个有效:

Data$X1<-as.character(Data$X1)
Data$GEOID<-as.character(Data$BLKIDFP00)
Data<-within(Data,X1<-ifelse(is.na(Data$X1),GEOID,Data$X2)) 

但我承认我只有间歇性的运气。


0
投票

你也可以尝试一下elseif。

x <- 1
if (x ==1){
    print('same')
} else if (x > 1){
    print('bigger')
} else {
    print('smaller')
}
© www.soinside.com 2019 - 2024. All rights reserved.