在R中使用多个条件的ifelse语句

29

使用以下示例数据,我正在尝试基于三个条件变量(Denial1、Denial2和Denial3)的值创建一个新变量“Den”(值为“0”或“1”)。

如果任何一个条件变量为“0”,则我希望得到“0”,只有每个具有值的条件变量的值都为“1”(例如不是NA),我才希望得到“1”。

structure(list(Denial1 = NA_real_, Denial2 = 1, Denial3 = NA_real_, 
Den = NA), .Names = c("Denial1", "Denial2", "Denial3", "Den"
), row.names = 1L, class = "data.frame")

我尝试了以下两个命令,并导致"Den"的值缺失NA:

DF$Den<-ifelse (DF$Denial1 < 1 | DF$Denial2 < 1 | DF$Denial3 < 1, "0", "1")

DF$Den<-ifelse(DF$Denial1 < 1,"0", ifelse (DF$Denial2 < 1,"0", ifelse(DF$Denial3 < 1,"0", "1")))

有人能演示一下如何做吗?


1
可能有帮助:https://dev59.com/3WMl5IYBdhLWcg3w7qlq?rq=1 - jaimedash
1
@jaimedash,感谢您提供的链接。在发布问题之前,我已经阅读了它,并在上面包含了嵌套ifelse语句的脚本。但我仍然可能在某个地方犯了错误。 - user3594490
你需要同时满足两个条件:1)不是 NA 2)小于 1。虽然不美观,但使用多个类似 (DF$Denial1 < 1 & !is.na(DF$Denial1) ) 的表达式,并用 & 连接它们,就可以实现目的。(已修改为使用逐元素运算符 & - jaimedash
@jaimedash 非常感谢,这个方法可行但是很丑! - user3594490
太棒了。你应该将可工作的丑陋代码发布为答案。 - jaimedash
你的问题表述是否有误?你说你只想要一个1,当且仅当每个条件变量都有一个值,并且这个值为“1”(例如,不是NA)。这难道不意味着所有的值都需要是1才能使Den为1吗?然而,你的答案(以及显然你真正想要的)是如果Denial1、Denial2或Denial3中的任何一个为1,则Den为1。 - Meg
5个回答

33

根据@jaimedash和@Old_Mortality的建议,我找到了一个解决方案:

DF$Den <- ifelse(DF$Denial1 < 1 & !is.na(DF$Denial1) | DF$Denial2 < 1 &  
!is.na(DF$Denial2) | DF$Denial3 < 1 & !is.na(DF$Denial3), "0", "1")

如果所有条件变量的值都为NA,则确保返回NA值:

DF$Den <- ifelse(is.na(DF$Denial1) & is.na(DF$Denial2) & is.na(DF$Denial3), 
NA, DF$Den)

8

你觉得怎么样?

DF$Den<-ifelse (is.na(DF$Denial1) | is.na(DF$Denial2) | is.na(DF$Denial3), "0", "1")

我来尝试澄清一下:如果条件变量的值缺失,我不希望出现“0”。如果任何一个条件变量为“0”,我希望在“Den”中出现“0”。只有当所有没有缺失值的条件变量都为“1”时,“Den”中才会出现“1”。这样是否有帮助? - user3594490
如果有一个缺失,你想要什么? - Old_Mortality
如果所有三个条件变量都是缺失值,那么我才希望“Den”是缺失的。但我希望“Den”的值基于具有非缺失值(即“0”或“1”)的条件变量。你上面的例子给了我一个“0”,而这个条件应该产生一个“1”,因为唯一具有值(“Denial2”)的条件变量的值为“1”。 - user3594490
必须是一个语句? - Old_Mortality
不,我想我明白你的意思了,我可以创建变量,然后使用另一个条件语句来根据三个条件变量是否缺失来更改它的值。 - user3594490
是的,大致上就是这样。 - Old_Mortality

4

这有一个更简单的解决方案。您描述的是&操作符的自然行为,因此可以使用原始方法实现:

> c(1,1,NA) & c(1,0,NA) & c(1,NA,NA)
[1]  TRUE FALSE    NA

如果所有的值都是1,则返回1。如果有任何一个值为0,则返回0。如果所有的值都是NA,则返回NA。

在你的情况下,代码应该是:

DF$Den<-DF$Denial1 & DF$Denial2 & DF$Denial3

为了使其起作用,您需要停止使用“character”并改用“numeric”或“logical”类型。

1
OP的结果提供了1,而你的结果提供了NA。 - Meg

4
非常简单的使用 any
df <- <your structure>

df$Den <- apply(df,1,function(i) {ifelse(any(is.na(i)) | any(i != 1), 0, 1)})

6
想知道如何在dplyr::mutate中使用这个功能? - HNSKD
2
@HNSKD 在那里我会使用 dplyr::if_else - M--

3

使用dplyr的另一种解决方案是:

df <- ## your data ##
df <- df %>%
        mutate(Den = ifelse(any(is.na(Den)) | any(Den != 1), 0, 1))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接