r语言 - 如何使用case_when()来排除多个条件



在我们的研究中,当参与者有高血压病史,或收缩压130 mmHg,或舒张压80 mmHg,或接受降压治疗时,视为高血压病例。我使用下面列出的两种不同的方法来创建最终的高血压状态,方法1的结果是正确的,而方法2的结果是错误的。我的问题是如何通过使用方法2中的case_when()函数来创建最终的高血压状态?

#-------------------------- data set
# id: id number of participants
# hptn_his: self-reported history of hypertension (0 means no, 1 or 2 mean yes)
# sbp: systolic blood pressure (mmHg)
# dbp: diastolic blood pressure (mmHg)
# treat: whether recieved the antihypertensive treatment (0 means no, 1 means yes)
id<-c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24)
hptn_his<-c(0, NA, NA, NA, NA, NA, 2, 2, 2, 0, 0, NA, NA, 0, 0, 0, 0, 0, 0, NA, 0, 1, 1, 1)
sbp<-c(NA, NA, NA, NA, NA, 110, 105, 115, NA, NA, NA, NA, 109, 102, 140, 136, 150, 126, 112, 147, NA, NA, 155, 124)
dbp<-c(NA, NA, NA, NA, NA, 61, 62, 84, NA, NA, NA, NA, 75, 67, 74, 67, 58, 50, 45, 48, NA, NA, 80, 74)
treat<-c(NA, NA, NA, 1, NA, NA, NA, 1, NA, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, 1, 1, NA, 1, NA)

mydata<-as.data.frame(cbind(id,hptn_his,sbp,dbp,treat))

mydata

id hptn_his sbp dbp treat
1   1        0  NA  NA    NA
2   2       NA  NA  NA    NA
3   3       NA  NA  NA    NA
4   4       NA  NA  NA     1
5   5       NA  NA  NA    NA
6   6       NA 110  61    NA
7   7        2 105  62    NA
8   8        2 115  84     1
9   9        2  NA  NA    NA
10 10        0  NA  NA    NA
11 11        0  NA  NA     1
12 12       NA  NA  NA    NA
13 13       NA 109  75    NA
14 14        0 102  67    NA
15 15        0 140  74    NA
16 16        0 136  67    NA
17 17        0 150  58    NA
18 18        0 126  50    NA
19 19        0 112  45    NA
20 20       NA 147  48     1
21 21        0  NA  NA     1
22 22        1  NA  NA    NA
23 23        1 155  80     1
24 24        1 124  74    NA

#-------------------------- method 1, correct
mydata<-within(mydata,{ 
hptn1<-NA 
hptn1[hptn_his==0]<-0
hptn1[hptn_his==1|hptn_his==2|sbp>130|dbp>80|treat==1]<-1
})

table(mydata$hptn1)

0  1 
5 13

#-------------------------- method 2, incorrect 
library("dplyr")
mydata<-mydata%>%
mutate(
hptn2=case_when(hptn_his==0~0,
hptn_his==1|hptn_his==2|sbp>130|dbp>80|treat==1~1,
TRUE~NA_real_))

table(mydata$hptn2)

0  1 
10  8

#-------------------------- comparison
# hptn1: hypertension status by method 1 (0 means no, 1 means yes), correct
# hptn2: hypertension status by method 2 (0 means no, 1 means yes), incorrect
mydata

id hptn_his sbp dbp treat hptn1 hptn2
1   1        0  NA  NA    NA     0     0
2   2       NA  NA  NA    NA    NA    NA
3   3       NA  NA  NA    NA    NA    NA
4   4       NA  NA  NA     1     1     1
5   5       NA  NA  NA    NA    NA    NA
6   6       NA 110  61    NA    NA    NA
7   7        2 105  62    NA     1     1
8   8        2 115  84     1     1     1
9   9        2  NA  NA    NA     1     1
10 10        0  NA  NA    NA     0     0
11 11        0  NA  NA     1     1     0
12 12       NA  NA  NA    NA    NA    NA
13 13       NA 109  75    NA    NA    NA
14 14        0 102  67    NA     0     0
15 15        0 140  74    NA     1     0
16 16        0 136  67    NA     1     0
17 17        0 150  58    NA     1     0
18 18        0 126  50    NA     0     0
19 19        0 112  45    NA     0     0
20 20       NA 147  48     1     1     1
21 21        0  NA  NA     1     1     0
22 22        1  NA  NA    NA     1     1
23 23        1 155  80     1     1     1
24 24        1 124  74    NA     1     1

case_when返回第一个为true的值。对于使用第二种方法出现错误的记录,这些记录发生在hptn_hist==0在附加问题之前首先触发时。

简短的回答,交换顺序:

mydata<-mydata%>%
mutate(
hptn3=case_when(hptn_his==1|hptn_his==2|sbp>130|dbp>80|treat==1~1,
hptn_his==0~0,
TRUE~NA_real_))

更详细的说明:

  • 在您的第一种方法中,您正在使用覆盖。hptn1[hptn_his==0]<-0中的一些值被hptn1[hptn_his==1|hptn_his==2|sbp>130|dbp>80|treat==1]<-1覆盖。如果后面的值覆盖前面的值,这是正确的顺序。

  • 在第二种方法中,case_when只返回第一个真值。所以后面的值不能覆盖前面的值。因此正确的顺序是hptn_his==1|hptn_his==2|sbp>130|dbp>80|treat==1hptn_his==0之前。

另一个是这样想的:

case_when(condition1 ~ 1,
condition2 ~ 2,
condition3 ~ 3,
...)

等价于:

case_when(condition1 ~ 1,
!condition1 & condition2 ~ 2,
!condition1 & !condition2 & condition3 ~ 3,
...)

最新更新