【问题标题】:flag rows in groups with multiple conditions标记具有多个条件的组中的行
【发布时间】:2018-09-06 17:01:47
【问题描述】:

我查看了这里和其他地方,但找不到完全符合我希望使用 R 完成的任务。

我有类似下面的数据,其中 col1 是唯一 ID,col2 是组 ID 变量,col3 是状态码。我需要标记具有相同组 ID 的所有行,并且这些行中的任何一个都有特定的状态代码,在本例中为 X,为 == 1,否则为 0。

ID   GroupID    Status   Flag
 1    100        A        1
 2    100        X        1
 3    102        A        0
 4    102        B        0
 5    103        B        1 
 6    103        X        1
 7    104        X        1
 8    104        X        1
 9    105        A        0
 10   105        C        0

我尝试写一些 ifelse where groupID == groupID and status == X then 1 else 0,但这不起作用。状态的模式是随机的。在此示例中,GroupID 是唯一的对,但我不想假设在代码中,b/c 我有其他实例,其中 GroupID 中有 3 行或更多行。

如果这是开放式 IE 会很有帮助,我可以在必要时添加其他条件,例如,对于每个匹配的组 ID,其中 Status == X,以及其他或其他等。

谢谢!

【问题讨论】:

    标签: r if-statement grouping


    【解决方案1】:

    使用 dplyr 包可以轻松完成此类基于组的操作。

    数据:

    library(dplyr)
    
    txt <- 'ID   GroupID    Status
    1    100        A        
    2    100        X        
    3    102        A        
    4    102        B        
    5    103        B         
    6    103        X        
    7    104        X        
    8    104        X        
    9    105        A        
    10   105        C        '
    
    df <- read.table(text = txt, header = T)
    

    一旦我们有了数据框,我们就可以使用group_by 函数建立 dplyr 组。然后将对每个组应用 mutate 命令,为每一行创建一个新的列条目。

    df.new <- df %>% 
      group_by(GroupID) %>% 
      mutate(Flag = as.numeric(any(Status == 'X')))
    
    # A tibble: 10 x 4
    # Groups:   GroupID [5]
          ID GroupID Status  Flag
       <int>   <int> <fct>  <dbl>
     1     1     100 A          1
     2     2     100 X          1
     3     3     102 A          0
     4     4     102 B          0
     5     5     103 B          1
     6     6     103 X          1
     7     7     104 X          1
     8     8     104 X          1
     9     9     105 A          0
    10    10     105 C          0
    

    【讨论】:

    • 惊人的不同路径获得相同的结果!我想出了一个不同的,看起来不那么整洁的dplyr 解决方案:df.new&lt;- df %&gt;% group_by(GroupID) %&gt;% mutate(Flag = ifelse(sum(grepl("X",Status))&gt;0,1,0))
    【解决方案2】:

    从基础 R

    ave(df$Status=='X',df$GroupID,FUN=any)
     [1]  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
    

    【讨论】:

    • 这很有帮助,感谢 base R 中的示例。
    • @Adam_S yw :-) 快乐编码
    【解决方案3】:

    Data.table方式:

    library(data.table)
    setDT(df)
    
    df[ , flag := sum(Status == "X") > 0, by=GroupID]
    

    【讨论】:

      【解决方案4】:

      使用data.table的替代方法

      library(data.table)
      dt <- read.table(stringsAsFactors = FALSE,text = "ID   GroupID    Status
                       1    100        A
                       2    100        X
                       3    102        A
                       4    102        B
                       5    103        B 
                       6    103        X
                       7    104        X
                       8    104        X
                       9    105        A
                       10   105        C", header=T)
      setDT(dt)[,.(ID,Status, Flag=ifelse("X"%in% Status,1,0)),by=GroupID]
      
      #returns
         GroupID ID Status Flag
       1:     100  1      A    1
       2:     100  2      X    1
       3:     102  3      A    0
       4:     102  4      B    0
       5:     103  5      B    1
       6:     103  6      X    1
       7:     104  7      X    1
       8:     104  8      X    1
       9:     105  9      A    0
      10:     105 10      C    0
      

      【讨论】:

        【解决方案5】:

        base R 选项与rowsum

        i1 <- with(df1, rowsum(+(Status == "X"), group = GroupID) > 0)
        transform(df1, Flag = +(GroupID %in% row.names(i1)[i1]))
        

        或者使用table

        df1$Flag <- +(with(df1, GroupID %in% names(which(table(GroupID,
                          Status == "X")[,2]> 0))))
        

        【讨论】:

          猜你喜欢
          • 2018-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-23
          • 2017-05-29
          • 1970-01-01
          • 2019-05-19
          相关资源
          最近更新 更多