基于包含值因子的列值的子数据框

Bea*_*ant 0 time r subset dataframe

我有一个数据框,其中包含一列,其中前一行和当前行之间存在时间差(以小时为单位)。这些行本身就是一个长序列。

我想要对数据帧进行子集化,以便时间差异是规则的 (16 小时),并删除不属于 16 小时“步骤”的行。然而,在计算中不应该仅仅跳过NA时间差(例如,时间差为8、8的行一起是16小时的步长,但具有8、NA、8的三行则不是)。相反,应从此 NA 开始重新计算 16 小时的时间差。

因此,如果一个或多个时间差为 4 或 8 小时,但加起来不能减少到 16 小时的单个步骤,则各个值也应变为 NA,请参见下文。

当第1-3行或1-4行之间形成16小时的步长时,应分别删除第2行或2-3行。

不幸的是,之前提供的答案似乎不适用于我的数据,输出中仅保留了“16h 步骤”的一小部分。我在下面提供了一个新示例,因为我的示例可能不具有代表性,以及给我的代码

输入:

test

ID      Datetime        diff_h
134_18  7/27/2018 0:00  NA
134_18  7/27/2018 19:00 19
134_18  7/28/2018 0:00  5
134_18  7/28/2018 8:00  8
134_18  7/28/2018 16:00 8
134_18  7/29/2018 0:00  8
134_18  7/29/2018 8:00  8
134_18  7/29/2018 12:00 4
134_18  7/30/2018 16:00 4
134_18  7/30/2018 20:00 4
134_18  7/30/2018 16:00 8
134_18  7/31/2018 0:00  8
134_18  7/31/2018 8:00  8
134_18  7/31/2018 16:00 8
134_18  8/1/2018 8:00   16
134_18  8/1/2018 16:00  8
134_18  8/2/2018 0:00   8
134_18  8/2/2018 8:00   8
134_18  8/2/2018 16:00  8
Run Code Online (Sandbox Code Playgroud)

(只是一个示例,还有数千行)请注意,在代码中,我建议删除, %>% select(-grp) %>%因为它返回“未使用的参数”错误!

data1 <- test %>% 
  group_by(ID, grp = rleid(diff_h %/% 16)) %>% 
  mutate(diff_h = cumsum(diff_h), 
         diff_h = replace(diff_h, n() ==1 & diff_h != 16, NA_real_))  %>% 
  ungroup %>%
  filter(diff_h == 16|is.na(diff_h))

data1
134_18  7/27/2018 0:00  NA  1
134_18  7/27/2018 19:00 NA  2
134_18  8/1/2018 8:00   16  4
134_18  8/2/2018 0:00   16  5

Run Code Online (Sandbox Code Playgroud)

虽然我需要的输出是

ID  Datetime    diff_h
134_18  7/27/2018 0:00  NA
134_18  7/27/2018 19:00 NA
134_18  7/28/2018 0:00  NA
134_18  7/28/2018 16:00 16
134_18  7/29/2018 8:00  16
134_18  7/29/2018 12:00 NA
134_18  7/30/2018 16:00 16
134_18  7/31/2018 8:00  16
134_18  7/31/2018 16:00 NA
134_18  8/1/2018 8:00   16
134_18  8/2/2018 0:00   16
134_18  8/2/2018 16:00  16
Run Code Online (Sandbox Code Playgroud)

akr*_*run 5

我们可以创建一个分组列,rleid然后通过 grp 和“ID”获取累积和,并且filter仅获取“16”值或NA元素

\n
library(dplyr)\nlibrary(data.table)\ndf1 %>% \n  group_by(ID, grp = rleid(timediff %/% 16)) %>% \n  mutate(timediff = cumsum(timediff), \n  timediff = replace(timediff, n() ==1 & timediff != 16, NA_real_))  %>% \n  ungroup %>% \n  select(-grp) %>%\n  filter(timediff == 16|is.na(timediff))\n
Run Code Online (Sandbox Code Playgroud)\n

-输出

\n
# A tibble: 6 \xc3\x97 3\n  ID     dist timediff\n  <chr> <int>    <dbl>\n1 A        12       NA\n2 A         6       16\n3 A         2       16\n4 A         6       NA\n5 B         7       NA\n6 B         2       16\n
Run Code Online (Sandbox Code Playgroud)\n