如何在ifelse中包含NA?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在ifelse中包含NA?相关的知识,希望对你有一定的参考价值。
我正在尝试基于其他列的值的逻辑语句创建列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
我想为所有不是ID
的time
和所有不是NA
的type
制作一个新的列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
,我可以使用我现有的代码,但我不知道该怎么做。或者,我现有代码的结构可能需要完全改变吗?我感谢任何帮助!
你不能真正比较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
@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")
听起来你想要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")
所以,我听说这个有效:
Data$X1<-as.character(Data$X1)
Data$GEOID<-as.character(Data$BLKIDFP00)
Data<-within(Data,X1<-ifelse(is.na(Data$X1),GEOID,Data$X2))
但我承认我只有间歇性的运气。
你也可以尝试一下elseif。
x <- 1
if (x ==1){
print('same')
} else if (x > 1){
print('bigger')
} else {
print('smaller')
}
以上是关于如何在ifelse中包含NA?的主要内容,如果未能解决你的问题,请参考以下文章