如何使用 case_when() 来排他多个条件
How to use case_when() for exclusive multiple conditions
在我们的研究中,如果参与者 he/she 有高血压病史,或收缩压 >130 mmHg,或舒张压 >80 mmHg,或接受抗高血压治疗,则被视为高血压病例.我使用下面列出的两种不同方法创建最终高血压状态,方法 1 的结果正确但方法 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
returns 第一个值为真。对于使用第二种方法出现错误的记录,这些记录在 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
returns 只有第一个真值。所以后面的值不能覆盖前面的值。因此正确的顺序是 hptn_his==1|hptn_his==2|sbp>130|dbp>80|treat==1
在 hptn_his==0
.
之前
另一个是想到这个:
case_when(condition1 ~ 1,
condition2 ~ 2,
condition3 ~ 3,
...)
相当于:
case_when(condition1 ~ 1,
!condition1 & condition2 ~ 2,
!condition1 & !condition2 & condition3 ~ 3,
...)
在我们的研究中,如果参与者 he/she 有高血压病史,或收缩压 >130 mmHg,或舒张压 >80 mmHg,或接受抗高血压治疗,则被视为高血压病例.我使用下面列出的两种不同方法创建最终高血压状态,方法 1 的结果正确但方法 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
returns 第一个值为真。对于使用第二种方法出现错误的记录,这些记录在 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
returns 只有第一个真值。所以后面的值不能覆盖前面的值。因此正确的顺序是hptn_his==1|hptn_his==2|sbp>130|dbp>80|treat==1
在hptn_his==0
.
另一个是想到这个:
case_when(condition1 ~ 1,
condition2 ~ 2,
condition3 ~ 3,
...)
相当于:
case_when(condition1 ~ 1,
!condition1 & condition2 ~ 2,
!condition1 & !condition2 & condition3 ~ 3,
...)