使用数据框进行Group_by过滤

时间:2020-11-02 00:29:46

标签: filter dplyr group-by

我有一个由时间序列数据组成的小标题。在每个时间步上,我都有给定的载荷(Loadz)和位移(Dispz),它们与测试标识(FName)相关联:

# A tibble: 15,926 x 5
# Groups:   FName [92]
   TIMESTAMP             FName  Dispz Loadz Failflag
   <chr>                 <chr>  <dbl> <dbl> <chr>   
 1 2020-09-19 14:56:46   D-H1  0       0    ""      
 2 2020-09-19 14:56:46.5 D-H1  0.019   3.61 ""      
 3 2020-09-19 14:56:47   D-H1  0.04    8.91 ""      
 4 2020-09-19 14:56:47.5 D-H1  0.06   14.5  ""      
 5 2020-09-19 14:56:48   D-H1  0.0790 20.1  ""      
 6 2020-09-19 14:56:48.5 D-H1  0.101  25.7  ""      
 7 2020-09-19 14:56:49   D-H1  0.12   31.2  ""      
 8 2020-09-19 14:56:49.5 D-H1  0.142  36.1  ""      
 9 2020-09-19 14:56:50   D-H1  0.162  40.9  ""      
10 2020-09-19 14:56:50.5 D-H1  0.183  45.9  ""    

我有下面的代码,可以过滤出所有低于某个阈值的载荷和位移(对于大于0.02mm的位移和超过10N的载荷),然后进行扫描(或清零),以便所有测试均从原点开始。 / p>

dat<-df%>%
  group_by(FName)%>%
  filter(Dispz>0.02)%>%
  filter(Loadz>10)%>%
  mutate_if(is.numeric,funs(.-first(.)))%>%
  slice(1:which.max(Loadz))

但是,我有一些测试有一些错误,需要手动进行强制。这就是我遇到麻烦的地方。

在需要将数据归零的位置,我具有那些行为不当的测试的FName标识以及相关的TIMESTAMP值,但是找到了一种方法来使用查找数据框进行过滤,该查找数据框也​​从该查找中查找值琐事证明是具有挑战性的。

    # Identify FName ids that need to be manually modified
    badlist<-c("WR-H2.2",
               "WR-H2.3", 
               "WR-H2.4")
#Find associated timestamps with each respective FName label
        timelist<-c("2020-10-04 12:31:06",
                    "2020-10-04 12:32:28",
                    "2020-10-04 12:33:46.5")

#Sample ID, and associated row to 
maninput<-tibble(x=badlist,y=timelist)

我的R语言不是特别好,因此下面令人遗憾的伪代码尝试表达我的意图。本质上,它需要根据其分组原因查找FName变量(这是我最大的问题,是否使用“ quo”?),然后找到关联的TIMESTAMP值作为过滤器的变量。

Newdat<-dat%>%
    group_by(FName)%>%
    filter(TIMESTAMP>maninput[FName== "group_by(FName)",2]

我很困惑,但是感觉答案很简单。

1 个答案:

答案 0 :(得分:1)

这是联接的主要用例。您可以通过left_joinmaninput修饰小标题,然后通过与添加的列进行比较进行过滤来轻松解决此问题。

您实际上并没有提供任何可直接使用的示例数据,所以我做了自己的事情:

library(tidyverse)
library(lubridate)

set.seed(0)

max_time = ymd_hms("2020-11-02 11:07:00 CET")
names = c("D-H1", "WR-H2.2", "WR-H2.3", "WR-H2.4")
obs = 10

df = names %>%
  map(~tibble(FName = .x,
              Dispz = cumsum(abs(rnorm(obs)) * 0.3),
              Loadz = cumsum(abs(rnorm(obs)) * 10),
              TIMESTAMP = seq(max_time - obs, max_time - 1, length.out = obs),
              Failflag = "")) %>%
  bind_rows()

dat = df %>%
  group_by(FName) %>%
  filter(Dispz > 0.02) %>%
  filter(Loadz > 10) %>%
  mutate(across(where(is.numeric), ~.x - first(.x))) %>%
  slice(1:which.max(Loadz)) %>%
  ungroup()

badlist = c("WR-H2.2", "WR-H2.3")
timelist = c("2020-11-02 11:06:54 CET", "2020-11-02 11:06:57 CET")
maninput = tibble(x = badlist, y = ymd_hms(timelist))

现在您可以进行加入了

newdat = dat %>%
  group_by(FName) %>%
  left_join(maninput, by = c("FName" = "x")) %>%
  filter(is.na(y) | TIMESTAMP > y) %>%
  select(-y)

我们首先按照说明加入maninput表,为其中yFName中的x值相匹配的每个测试创建一个maninput列。然后,我们进行过滤,仅选择y列为NA(即maninput中没有匹配检验)或TIMESTAMP大于{ {1}}列(即观察发生在y中的指定时间之后)。然后,我们从数据中删除了maninput列,因为不再需要它。

这会导致小标题,其中所选测试仅在其各自的时间戳之后才包含数据,我很确定这是您要查找的内容:

y