【问题标题】:How to use case_when() for exclusive multiple conditions如何将 case_when() 用于独占多个条件
【发布时间】:2021-08-03 03:57:51
【问题描述】:

在我们的研究中,如果参与者有高血压病史,或收缩压>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

【问题讨论】:

    标签: r dplyr case


    【解决方案1】:

    case_when 返回第一个为真的值。对于使用您的第二种方法出现错误的记录,当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]&lt;-0 中的一些值会被hptn1[hptn_his==1|hptn_his==2|sbp&gt;130|dbp&gt;80|treat==1]&lt;-1 覆盖。如果后面的值覆盖前面的一次,这是正确的顺序。

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

    另一个是想到这个:

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

    相当于:

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

    【讨论】:

    • 谢谢西蒙!这真的很有帮助!我只是觉得 case_when () 很酷,但有时不受控制。
    • 此外,当独占多个条件的数量增加时,case_when() 的结构预计会更复杂。 library("dplyr") (或链接到 dplyr)中是否可以使用其他函数来处理除 case_when() 之外的覆盖条件?
    • 我不知道任何等效于case_when 的覆盖方法。一般来说,我会推荐非重写方法,因为它们往往更容易理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2017-01-13
    相关资源
    最近更新 更多