【问题标题】:Select multiple columns and filter on specific and/or conditions then form new Column选择多个列并根据特定和/或条件进行过滤,然后形成新列
【发布时间】:2021-04-06 19:02:54
【问题描述】:

我正在使用一个非常大的患者记录数据库。 基本上我试图根据某些诊断代码对患者进行分类。 每位患者可能有 1-10 个诊断代码(DX1、DX2、DX3、DX4、DX5、DX6、DX7、 DX8、DX9、DX10)。 我很难使用多个条件进行编码以尽可能过滤每个 DX 列 有不同的安排。

Example Dataset: 
DX1<-c("05", "89", "99", "87", "05", "67")
DX2<-c("87", "05", "21", "26", "23", "44","89", "13", "2" )
DX3<-c("04", "99","23", "05", "57", "16", "90", "89", "87")
DX4<-c("05", "26","21")
DX5<-c("67", "86","44", "63", "18", "87", "87", "05")
DX6<-c("75", "06","24", "02", "86", "15", "01", "87")
DX7<-c("86", "87","66", "56", "65", "05", "72")
install.packages("qpcR")                           
library("qpcR")
Patientdata <- qpcR:::cbind.na(DX1, DX2, DX3, DX4, DX5, DX6, DX7) 
data.frame(Patientdata)


   DX1 DX2 DX3  DX4  DX5  DX6  DX7
1   05  87  04   05   67   75   86
2   89  05  99   26   86   06   87
3   99  21  23   21   44   24   66
4   87  26  05 NA   63   02   56
5   05  23  57 NA   18   86   65
6   67  44  44 NA   87   15   05
7 NA  89  90 NA   87   01   72
8 NA  13  89 NA   05   87 NA
9 NA   2  87 NA NA NA NA

我想用(05、5 或 02 或 2 或 62)AND(87 或 087 或 0086 或 089 或 89)

Patientdata<- Patientdata%>% mutate_at(vars(DX1, DX2, DX3, DX4, DX5, DX6, DX7),
Diagnosis= ifelse(. %in% c("05"| "5"| "02"| "2"| "36"| "62"|"0062") &
c("87"| "087"| "86"| "0086"| "89"| "089"), "Yes"))

我想要什么:

ID DX1 DX2 DX3 DX4 DX5 DX6 DX7 Diagnosis
1 05 87 04 05 67 75 86 Yes
2 89 05 99 26 86 06 87 Yes
3 99 21 23 21 44 24 66
4 87 26 05 NA 63 02 56 Yes
5 05 23 57 NA 18 86 65
6 67 44 46 NA 87 15 05 Yes
7 NA 89 90 NA 87 01 72
8 NA 13 89 NA 05 87 NA Yes
9 NA 2 87 NA NA NA NA Yes

非常感谢任何帮助!

【问题讨论】:

  • ID 5 也应该保留吗?
  • 是的,对不起,我只是在编造例子

标签: r tidyverse dplyr


【解决方案1】:

这是一个没有添加诊断变量的tidyverse 方法:

rowAny <- function(x) rowSums(x) > 0

Patientdata %>% 
  mutate(ID = row_number()) %>% 
  filter(
    rowAny(
      across(
        starts_with("DX"), 
      ~ .x %in% c("05", "5", "02", "2", "36", "62","0062"), 
      .x %in% c("87", "087", "86", "0086", "89", "089")))) 

您的示例中有 ID,但示例数据中没有,这就是在上面添加它的原因。

这给了我们:

   DX1 DX2 DX3  DX4  DX5  DX6  DX7 ID
1   05  87  04   05   67   75   86  1
2   89  05  99   26   86   06   87  2
3   87  26  05 <NA>   63   02   56  4
4   05  23  57 <NA>   18   86   65  5
5   67  44  16 <NA>   87   15   05  6
6 <NA>  13  89 <NA>   05   87 <NA>  8
7 <NA>   2  87 <NA> <NA> <NA> <NA>  9

【讨论】:

  • 感谢您的回复,我其实没有ID,但在我的数据集中有。有没有一种方法可以添加列,而不是行摘要,即使它是二进制的,对于上述所需的诊断而言,否?
【解决方案2】:

更新

在 akrun 的帮助下。非常感谢。现在我得到了 OP 想要的解决方案。

Patientdata %>% 
  as_tibble %>% 
  rowwise () %>% 
  mutate(Diagnosis = if(any(c_across(starts_with("DX")) %in% vector)) "Yes" else "No") %>% 
  ungroup ()

输出:

# A tibble: 9 x 8
  DX1   DX2   DX3   DX4   DX5   DX6   DX7   Diagnosis
  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>    
1 05    87    04    05    67    75    86    Yes      
2 89    05    99    26    86    06    87    Yes      
3 99    21    23    21    44    24    66    No       
4 87    26    05    NA    63    02    56    Yes      
5 05    23    57    NA    18    86    65    Yes      
6 67    44    16    NA    87    15    05    Yes      
7 NA    89    90    NA    87    01    72    Yes      
8 NA    13    89    NA    05    87    NA    Yes      
9 NA    2     87    NA    NA    NA    NA    Yes

第一个解决方案 我不确定您是否需要这种解决方案。 基本上创建您感兴趣的项目的矢量 然后使用across 和ifelse

library(tidyverse)

vector <- c("05", "5", "02", "2", "36", "62", "0062", "87", "087", "86", "0086", "89", "089")

Patientdata %>%
  as_tibble() %>% 
  mutate(Diagnosis = across(starts_with("DX"),
                            ~ ifelse(. %in% vector, "Yes", "No")))
# A tibble: 9 x 8
  DX1   DX2   DX3   DX4   DX5   DX6   DX7   Diagnosis$DX1 $DX2  $DX3  $DX4  $DX5  $DX6  $DX7 
  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>         <chr> <chr> <chr> <chr> <chr> <chr>
1 05    87    04    05    67    75    86    Yes           Yes   No    Yes   No    No    Yes  
2 89    05    99    26    86    06    87    Yes           Yes   No    No    Yes   No    Yes  
3 99    21    23    21    44    24    66    No            No    No    No    No    No    No   
4 87    26    05    NA    63    02    56    Yes           No    Yes   No    No    Yes   No   
5 05    23    57    NA    18    86    65    Yes           No    No    No    No    Yes   No   
6 67    44    16    NA    87    15    05    No            No    No    No    Yes   No    Yes  
7 NA    89    90    NA    87    01    72    No            Yes   No    No    Yes   No    No   
8 NA    13    89    NA    05    87    NA    No            No    Yes   No    Yes   Yes   No   
9 NA    2     87    NA    NA    NA    NA    No            Yes   Yes   No    No    No    No   

【讨论】:

  • 原因是您在循环 across 时指定名称,从而导致单个 list 列。在这里,您可以使用.names 来修改列的名称,即Patientdata %&gt;% as_tibble() %&gt;% mutate(across(starts_with("DX"), ~ ifelse(. %in% vector, "Yes", "No"), .names = "Diagnosis_{.col}"))
  • 非常感谢阿克伦。是否可以在没有 $DX1...$D7 的 DX7 之后只创建一个诊断列。就像操作所需的输出一样!!!非常感谢。
  • @TarJee 抱歉,我没有检查 OP 的帖子以获得预期的输出。为此,您需要c_across 即Patientdata %&gt;% as_tibble %&gt;% rowwise %&gt;% mutate(Diagnosis = if(any(c_across(starts_with("DX")) %in% vector)) "Yes" else "No") %&gt;% ungroup
  • 感谢大家的反馈。有没有办法只制作一列?另外,正如我提到的,我正在尝试选择您提到的特定项目。如果患者在一列中有 5 个诊断代码中的 1 个,但在另一列中也有 1 或 5 个另一个诊断代码。这就是为什么它必须以各种排列方式搜索列以查看诊断列是否符合纳入标准。没关系是的,不
  • 我添加了一个答案,但这确实是下面你们的问题
猜你喜欢
  • 2021-12-19
  • 2017-03-22
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
  • 2018-11-15
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多