R:选择高于某个阈值的n个连续行中的第一行

col*_*ade 4 row r dataframe dplyr

我有一个带有MRN,日期和测试值的数据框.

我需要选择每个MRN的所有第一行,其中三个连续值大于0.5.

这是数据的示例版本:

   MRN Collected_Date   ANC
1  001     2015-01-02 0.345
2  001     2015-01-03 0.532
3  001     2015-01-04 0.843
4  001     2015-01-05 0.932
5  002     2015-03-03 0.012
6  002     2015-03-05 0.022
7  002     2015-03-06 0.543
8  002     2015-03-07 0.563
9  003     2015-08-02 0.343
10 003     2015-08-03 0.500
11 003     2015-08-04 0.734
12 003     2015-08-05 0.455
13 004     2014-01-02 0.001
14 004     2014-01-03 0.500
15 004     2014-01-04 0.562
16 004     2014-01-05 0.503
Run Code Online (Sandbox Code Playgroud)

示例代码:

df <- data.frame(MRN = c('001','001','001','001',
                         '002','002','002','002',
                         '003','003','003','003',
                         '004','004','004','004'), 
                 Collected_Date = as.Date(c('01-02-2015','01-03-2015','01-04-2015','01-05-2015',
                                            '03-03-2015','03-05-2015','03-06-2015','03-07-2015',
                                            '08-02-2015','08-03-2015','08-04-2015','08-05-2015',
                                            '01-02-2014','01-03-2014','01-04-2014','01-05-2014'), 
                                            format = '%m-%d-%Y'), 
                 ANC = as.numeric(c('0.345','0.532','0.843','0.932',
                         '0.012','0.022','0.543','0.563',
                         '0.343','0.500','0.734','0.455',
                         '0.001','0.500','0.562','0.503')))
Run Code Online (Sandbox Code Playgroud)

目前,我使用滞后函数来计算日期差异,然后过滤所有值> = 0.5,然后对值进行求和,这有助于选择THIRD值的日期.然后我减去两天来得到第一个值的日期:

   df %>% group_by(MRN) %>% 
    mutate(., days_diff = abs(Collected_Date[1] - Collected_Date)) %>% 
        filter(ANC >= 0.5) %>%
            mutate(days = days_diff + lag((days_diff))) %>%
                filter(days == 5) %>%
                    mutate(Collected_Date = Collected_Date - 2) %>%
                        select(MRN, Collected_Date)
Run Code Online (Sandbox Code Playgroud)

输出:

来源:本地数据框[2 x 2]组:MRN

  MRN Collected_Date
1 001     2015-01-03
2 004     2014-01-03
Run Code Online (Sandbox Code Playgroud)

必须有一种更简单/更优雅的方式.此外,如果测试日期之间存在差距,则无法给出准确的结果.

我希望这个例子的输出是:

   MRN Collected_Date   ANC     
1  001     2015-01-03 0.532
2  004     2014-01-03 0.500
Run Code Online (Sandbox Code Playgroud)

因此,如果至少三个连续测试值> = 0.5,则应返回FIRST值的日期.

如果至少有三个连续值> = 0.5,则应返回NA.

任何帮助是极大的赞赏!

非常感谢你!

cha*_*ers 8

最简单的方法是zoo结合使用库dplyr.在zoo包中有一个叫做的函数rollapply,我们可以用它来计算一个时间窗口的函数值.

在这个例子中,我们可以应用窗口来计算接下来三个值的最小值,然后应用指定的逻辑.

df %>% group_by(MRN) %>%
  mutate(ANC=rollapply(ANC, width=3, min, align="left", fill=NA, na.rm=TRUE)) %>%
  filter(ANC >= 0.5) %>%  
  filter(row_number() == 1)

#   MRN Collected_Date   ANC
# 1 001     2015-01-03 0.532
# 2 004     2014-01-03 0.500
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我们用来rollapply计算接下来的3个项目的最小值.要了解其工作原理,请比较以下内容:

rollapply(1:6, width=3, min, align="left", fill=NA) # [1]  1  2  3  4 NA NA
rollapply(1:6, width=3, min, align="center", fill=NA) # [1] NA  1  2  3  4 NA
rollapply(1:6, width=3, min, align="right", fill=NA) # [1] NA NA  1  2  3  4
Run Code Online (Sandbox Code Playgroud)

所以在我们的例子中,我们从左边开始对齐,所以它从当前位置开始,并期待接下来的2个值.

最后,我们按适当的值进行过滤,并对每个组进行第一次观察.