【问题标题】:Filter or ifelse across multiple columns跨多个列过滤或 ifelse
【发布时间】:2018-07-12 07:25:52
【问题描述】:

我正在研究病人生病时的沟通渠道。例如:一个人生病并去看医生(A),然后去医院(B),接触保险(C)等。每个患者的顺序不同。比如一个病人直接去医院,另一个人先查保险等等。我们全程跟踪病人,在接触到不同的权威机构后,让他们再填写一份调查表。因此,在每个权限(“步骤”)之后,我们得到了调查的分数。这给了我以下数据集设置(实际上它是一个非常大的数据集):

Patient<-c(1,1,1,1,1,1,1,2,2,2,2)
sample6<-c("A","A","A","A","A","A","A","A","A","A","A")
sample5<-c("Stop","B","B","B","B","B","B","Stop","C","C","C")
sample4<-c(NA,"Stop","C","C","C","C","C",NA, "Stop","F","F")
sample3<-c(NA,NA,"Stop","D","D","D","D",NA, NA,"Stop","G")
sample2<-c(NA,NA,NA,"Stop","E","E","E",NA, NA,NA,"Stop")
sample1<-c(NA,NA,NA,NA, "Stop","F","F",NA,NA,NA, NA)
sample0<-c(NA,NA,NA,NA, NA,"Stop","G",NA,NA,NA, NA)
sample00<-c(NA,NA,NA,NA, NA,NA,"Stop",NA,NA,NA, NA)
Score<-c(90,88,65,44,78,98,66,38,93,88,80)
Time<-c("01-01-2018", "02-01-2018", "03-01-2018", "04-01-2018", "05-01-2018", "06-01-2018", "07-01-2018","01-02-2018", "02-02-2018", "05-02-2018", "06-02-2018")

df<-data.frame("Patient"=Patient, "step0"=sample6, "step1"=sample5, "step2"=sample4, "step3"=sample3, "step4"=sample2, 
               "step5"=sample1,"step6"= sample0, "step7"=sample00, "Score"=Score, "Time"=Time)

> df
   Patient step0 step1 step2 step3 step4 step5 step6 step7 Score       Time
1        1     A  Stop  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>    90 01-01-2018
2        1     A     B  Stop  <NA>  <NA>  <NA>  <NA>  <NA>    88 02-01-2018
3        1     A     B     C  Stop  <NA>  <NA>  <NA>  <NA>    65 03-01-2018
4        1     A     B     C     D  Stop  <NA>  <NA>  <NA>    44 04-01-2018
5        1     A     B     C     D     E  Stop  <NA>  <NA>    78 05-01-2018
6        1     A     B     C     D     E     F  Stop  <NA>    98 06-01-2018
7        1     A     B     C     D     E     F     G  Stop    66 07-01-2018
8        2     A  Stop  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>    38 01-02-2018
9        2     A     C  Stop  <NA>  <NA>  <NA>  <NA>  <NA>    93 02-02-2018
10       2     A     C     F  Stop  <NA>  <NA>  <NA>  <NA>    88 05-02-2018
11       2     A     C     F     G  Stop  <NA>  <NA>  <NA>    80 06-02-2018

例如:第 1 行是权威 A 之后的调查分数,第 2 行是同一位患者,并且是权威 B 之后的调查分数等。 现在我想比较具有相同最终过程的列,我将以“F”为例,但也可以是“C”进行另一个分析。所以现在我想选择所有指示“F”作为最终权限的行和之前的行,以便我可以比较它们。

所以我想创建这个数据集:

   Patient step0 step1 step2 step3 step4 step5 step6 step7 Score       Time Indicator
1        1     A  Stop  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>    90 01-01-2018         0
2        1     A     B  Stop  <NA>  <NA>  <NA>  <NA>  <NA>    88 02-01-2018         0
3        1     A     B     C  Stop  <NA>  <NA>  <NA>  <NA>    65 03-01-2018         0
4        1     A     B     C     D  Stop  <NA>  <NA>  <NA>    44 04-01-2018         0
5        1     A     B     C     D     E  Stop  <NA>  <NA>    78 05-01-2018         Before
6        1     A     B     C     D     E     F  Stop  <NA>    98 06-01-2018         After
7        1     A     B     C     D     E     F     G  Stop    66 07-01-2018         0
8        2     A  Stop  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>    38 01-02-2018         0
9        2     A     C  Stop  <NA>  <NA>  <NA>  <NA>  <NA>    93 02-02-2018         Before
10       2     A     C     F  Stop  <NA>  <NA>  <NA>  <NA>    88 05-02-2018         After
11       2     A     C     F     G  Stop  <NA>  <NA>  <NA>    80 06-02-2018         0

我确实设法指出了包含“F”加上前一个的行​​:

ProcessColumns <- 2:9
d <- df[,ProcessColumns] == "F"
df$Indicator <- rowSums(d,na.rm=T)
df$filter[which(df$filter %in% 1)-1] <- "Before"
df$filter[which(df$filter %in% 1)] <- "After"

但现在它指示所有包含“F”的行,而不仅仅是最后..任何可以帮助我的人?

【问题讨论】:

    标签: r if-statement filter multiple-columns selection


    【解决方案1】:

    我们可以做类似的事情

    df %>% mutate(sum=rowSums(!is.na(.[2:9]))) %>% 
    group_by(Patient) %>% mutate(max = sum-max(sum), Indicator  = case_when(max == -2 ~ "Before", max == -1 ~ "After", TRUE ~ as.character(0)))
    
    # A tibble: 11 x 14
    # Groups:   Patient [2]
         Patient step0 step1 step2 step3 step4 step5 step6 step7 Score Time         sum   max Ind   
         <dbl> <fct> <fct> <fct> <fct> <fct> <fct> <fct> <fct> <dbl> <fct>      <dbl> <dbl> <chr> 
     1    1.00 A     Stop  NA    NA    NA    NA    NA    NA     90.0 01-01-2018  2.00 -6.00 0     
     2    1.00 A     B     Stop  NA    NA    NA    NA    NA     88.0 02-01-2018  3.00 -5.00 0     
     3    1.00 A     B     C     Stop  NA    NA    NA    NA     65.0 03-01-2018  4.00 -4.00 0     
     4    1.00 A     B     C     D     Stop  NA    NA    NA     44.0 04-01-2018  5.00 -3.00 0     
     5    1.00 A     B     C     D     E     Stop  NA    NA     78.0 05-01-2018  6.00 -2.00 Before
     6    1.00 A     B     C     D     E     F     Stop  NA     98.0 06-01-2018  7.00 -1.00 After 
     7    1.00 A     B     C     D     E     F     G     Stop   66.0 07-01-2018  8.00  0    0     
     8    2.00 A     Stop  NA    NA    NA    NA    NA    NA     38.0 01-02-2018  2.00 -3.00 0     
     9    2.00 A     C     Stop  NA    NA    NA    NA    NA     93.0 02-02-2018  3.00 -2.00 Before
    10    2.00 A     C     F     Stop  NA    NA    NA    NA     88.0 05-02-2018  4.00 -1.00 After 
    11    2.00 A     C     F     G     Stop  NA    NA    NA     80.0 06-02-2018  5.00  0    0 
    

    更新:灵感来自@Andre Elrico 的回答

    df %>% unite(All, matches("step"), sep="", remove=F ) %>% 
           mutate(Ind = str_detect(All,"BStop"), Indicator = case_when( lead(Ind) == TRUE ~ "Before", Ind == TRUE ~ "After", TRUE ~ as.character(0))) %>% 
           select(-All,-Ind)
    

    【讨论】:

    • 它看起来很不错,唯一的问题是“F”只是一个例子。我想比较不同的权限,顺序不同。例如,选择“B”作为最后一个权限的行是行不通的..
    • 我得到了不同的结果。可能是由于“掩蔽”。
    • @Lotw 感谢您指出这一点。请检查我的更新。谢谢
    • 啊,非常感谢!完美运行,运行起来:)
    【解决方案2】:

    或者你可以:

    library(dplyr)
    
    After_IND <- df %>% apply(.,1,paste,collapse="") %>% grepl("FStop",.)
    Before_IND<- lead(After_IND,1,F)
    
    df$Indicator <- 0
    df$Indicator[After_IND]<-"After"
    df$Indicator[Before_IND]<-"Before"
    
    #  Patient step0 step1 step2 step3 step4 step5 step6 step7 Score       Time Indicator
    #        1     A  Stop  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>    90 01-01-2018         0
    #        1     A     B  Stop  <NA>  <NA>  <NA>  <NA>  <NA>    88 02-01-2018         0
    #        1     A     B     C  Stop  <NA>  <NA>  <NA>  <NA>    65 03-01-2018         0
    #        1     A     B     C     D  Stop  <NA>  <NA>  <NA>    44 04-01-2018         0
    #        1     A     B     C     D     E  Stop  <NA>  <NA>    78 05-01-2018    Before
    #        1     A     B     C     D     E     F  Stop  <NA>    98 06-01-2018     After
    #        1     A     B     C     D     E     F     G  Stop    66 07-01-2018         0
    #        2     A  Stop  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>    38 01-02-2018         0
    #        2     A     C  Stop  <NA>  <NA>  <NA>  <NA>  <NA>    93 02-02-2018    Before
    #        2     A     C     F  Stop  <NA>  <NA>  <NA>  <NA>    88 05-02-2018     After
    #        2     A     C     F     G  Stop  <NA>  <NA>  <NA>    80 06-02-2018         0
    

    请注意:

    如果您想比较 B,例如。你必须改变:

    ... %>% grepl("BStop",.)
    

    【讨论】:

      【解决方案3】:

      tidyverse 有很多行,但通常有效。

      library(tidyverse)
      df %>%
        rownames_to_column() %>% 
        gather(k,v,-Patient,-rowname,-Score, -Time) %>% 
        group_by(rowname) %>% 
        mutate(Indicator=ifelse(any(v %in%"F" ),"After",NA)) %>% 
        spread(k,v)  %>% 
        arrange(as.numeric(rowname)) %>% 
        group_by(Patient) %>% 
        mutate(Indicator=ifelse(duplicated(Indicator), NA, Indicator)) %>% 
        mutate(Indicator2=ifelse(lead(Indicator) == "After", "Before", NA)) %>% 
        mutate(Indicator=ifelse(!is.na(Indicator2), Indicator2, Indicator)) %>% 
        select(Patient, starts_with("step"), Score, Time,Indicator, -Indicator2,-rowname) %>% 
        ungroup()
      # A tibble: 11 x 12
         Patient step0 step1 step2 step3 step4 step5 step6 step7 Score Time       Indicator
           <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <fct>      <chr>    
       1       1 A     Stop  NA    NA    NA    NA    NA    NA       90 01-01-2018 NA       
       2       1 A     B     Stop  NA    NA    NA    NA    NA       88 02-01-2018 NA       
       3       1 A     B     C     Stop  NA    NA    NA    NA       65 03-01-2018 NA       
       4       1 A     B     C     D     Stop  NA    NA    NA       44 04-01-2018 NA       
       5       1 A     B     C     D     E     Stop  NA    NA       78 05-01-2018 Before   
       6       1 A     B     C     D     E     F     Stop  NA       98 06-01-2018 After    
       7       1 A     B     C     D     E     F     G     Stop     66 07-01-2018 NA       
       8       2 A     Stop  NA    NA    NA    NA    NA    NA       38 01-02-2018 NA       
       9       2 A     C     Stop  NA    NA    NA    NA    NA       93 02-02-2018 Before   
      10       2 A     C     F     Stop  NA    NA    NA    NA       88 05-02-2018 After    
      11       2 A     C     F     G     Stop  NA    NA    NA       80 06-02-2018 NA  
      

      【讨论】:

        猜你喜欢
        • 2015-08-08
        • 2020-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-12
        相关资源
        最近更新 更多