【问题标题】:How to select rows with certain values within a group in R如何在R中的组中选择具有某些值的行
【发布时间】:2019-04-25 16:29:49
【问题描述】:

我正在 R 中训练自己的循环和函数(但目前处于非常基础的水平)。对于最近的一项研究,我需要准备以下数据:

我有一个如下所示的数据集:

dd <- read.table(text="
    event.timeline.ys     ID     year    group
1                   2     800033 2008    A
2                   1     800033 2009    A   
3                   0     800033 2010    A   
4                  -1     800033 2011    A   
5                  -2     800033 2012    A   
15                  0     800076 2008    B
16                 -1     800076 2009    B
17                  5     800100 2014    C     
18                  4     800100 2015    C   
19                  2     800100 2017    C   
20                  1     800100 2018    C   
30                  0     800125 2008    A    
31                 -1     800125 2009    A    
32                 -2     800125 2010    A", header=TRUE)

我想为每个人只保留 event.timeline.ys >= 0 的 last 行(这将是 ID 800033 的第 3 行)和 first event.timeline.ys

ID = 800100 的人在 event.timeline.ys 上没有任何负值。在这种情况下,我只想保留 event.timeline.ys >= 0 的最后一行。

最终的数据集将如下所示:

    event.timeline.ys     ID     year    group  
3                   0     800033 2010    A   
4                  -1     800033 2011    A      
15                  0     800076 2008    B
16                 -1     800076 2009    B 
20                  1     800100 2018    C   
30                  0     800125 2008    A    
31                 -1     800125 2009    A    

我考虑过使用 for 循环在每个 ID 中检查 last 行的 event.timeline.ys >= 0 和 first 行的事件。时间线.ys

有人有明智的建议吗?我也对不基于 for 循环或类似东西的其他解决方案持开放态度。

【问题讨论】:

    标签: r function for-loop


    【解决方案1】:

    这是在 dplyr 中使用 group_by 的一个选项:

    dd %>% group_by(ID, category = event.timeline.ys >= 0) %>% 
      filter(abs(event.timeline.ys) == min(abs(event.timeline.ys))) %>% 
      dplyr::select(-category) %>%
      as.data.frame
    
      category event.timeline.ys     ID year group
    1     TRUE                 0 800033 2010     A
    2    FALSE                -1 800033 2011     A
    3     TRUE                 0 800076 2008     B
    4    FALSE                -1 800076 2009     B
    5     TRUE                 1 800100 2018     C
    6     TRUE                 0 800125 2008     A
    7    FALSE                -1 800125 2009     A
    

    【讨论】:

    • 非常感谢您的快速帮助!恐怕我还有很多东西要学:) 但是这个论坛非常有帮助!再次感谢!
    • 我扩展了这个问题:stackoverflow.com/questions/55970694/… - 有人对如何根据组内其他两个变量的值组合选择行有明智的建议吗?
    【解决方案2】:

    ID分组,event.timesline.ys是否为负数。如果是否定的,则选择(slice)第一行,否则选择最后一行(即行n())。

    library(dplyr)
    
    dd %>% 
      mutate(neg = event.timeline.ys < 0) %>% 
      group_by(ID, neg) %>% 
      slice(if(neg[1]) 1 else n()) %>% 
      ungroup %>% 
      select(-neg)
    
    # # A tibble: 7 x 4
    #   event.timeline.ys     ID  year group
    #               <int>  <int> <int> <fct>
    # 1                 0 800033  2010 A    
    # 2                -1 800033  2011 A    
    # 3                 0 800076  2008 B    
    # 4                -1 800076  2009 B    
    # 5                 1 800100  2018 C    
    # 6                 0 800125  2008 A    
    # 7                -1 800125  2009 A   
    

    【讨论】:

      【解决方案3】:

      这是一种使用which()row_number() 为您感兴趣的行提取索引的方法

      library(dplyr)
      
      dd %>% 
        group_by(ID) %>% 
        filter(row_number() == last(which(event.timeline.ys >= 0)) | 
               row_number() == first(which(event.timeline.ys < 0)))
      

      我认为它的阅读方式与您用文字描述您所追求的方式相似,因此希望这是有道理的。

      【讨论】:

      【解决方案4】:

      这是data.table中的一种方法

      library(data.table)
      as.data.table(dd)[, .SD[c(last(which(event.timeline.ys >= 0)),
                                first(which(event.timeline.ys < 0)))],
                        by=ID]
      
      
             ID event.timeline.ys year group
      1: 800033                 0 2010     A
      2: 800033                -1 2011     A
      3: 800076                 0 2008     B
      4: 800076                -1 2009     B
      5: 800100                 1 2018     C
      6: 800125                 0 2008     A
      7: 800125                -1 2009     A
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-05
      • 2019-09-22
      • 2018-04-09
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 2017-02-26
      • 2013-04-13
      相关资源
      最近更新 更多