【问题标题】:Group_by filtering with a dataframeGroup_by 使用数据框过滤
【发布时间】:2020-11-02 00:29:46
【问题描述】:

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

# 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 的负载),然后扫描(或归零)所有内容,以便所有测试从原点开始。

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 值,但是找到了一种方法来过滤掉查找数据帧,该查找数据帧也从此查找中查找值事实证明,tibble 具有挑战性。

    # 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]

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

【问题讨论】:

  • 如果您提供一些您尝试对数据进行的“测试”的详细信息会更好。

标签: r filter dplyr group-by


【解决方案1】:

这是连接的主要用例。您可以通过 left_join 使用 maninput 来轻松解决此问题,然后通过与添加的列进行比较进行过滤。

您并没有真正提供任何可以直接使用的示例数据,所以我自己制作了:

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 表,为FNamemaninput 中的x 值匹配的每个测试创建一个y 列。然后我们过滤,只选择y 列是NA 的观察值(即maninput 中没有匹配的测试),或者TIMESTAMP 大于y 列(即观察发生在maninput 中的指定时间之后)。然后我们从数据中删除 y 列,因为它不再需要。

这会导致所选测试仅在其各自的时间戳之后具有数据的 tibble,我很确定这就是您要查找的内容:

# A tibble: 23 x 5
# Groups:   FName [4]
   FName   Dispz Loadz TIMESTAMP           Failflag
   <chr>   <dbl> <dbl> <dttm>              <chr>   
 1 D-H1    0      0    2020-11-02 11:06:51 ""      
 2 D-H1    0.399 11.5  2020-11-02 11:06:52 ""      
(...)     
 9 D-H1    2.46  49.7  2020-11-02 11:06:59 ""      
10 WR-H2.2 0.409 25.3  2020-11-02 11:06:55 ""      
11 WR-H2.2 0.735 35.2  2020-11-02 11:06:56 ""      
12 WR-H2.2 0.942 39.5  2020-11-02 11:06:57 ""      
13 WR-H2.2 1.33  51.9  2020-11-02 11:06:58 ""      
14 WR-H2.2 1.34  54.7  2020-11-02 11:06:59 ""      
15 WR-H2.3 1.98  41.2  2020-11-02 11:06:58 ""      
16 WR-H2.3 2.05  53.8  2020-11-02 11:06:59 ""      
17 WR-H2.4 0      0    2020-11-02 11:06:53 ""      
18 WR-H2.4 0.244  6.64 2020-11-02 11:06:54 ""      
(...)
23 WR-H2.4 0.949 43.8  2020-11-02 11:06:59 ""       

【讨论】:

  • 谢谢shizundeiku!为澄清起见,“人工输入”是否被视为正在连接到 dat=x 的“y”表?在这种情况下,by(FName="x") 做了什么?为什么 filter(is.na(y)) 不会影响坏名单上的所有 FName?这有点偏题了,但是有没有来源可以帮助我理解这是怎么回事:“mutate(across(where(is.numeric), ~.x - first(.x)))”? “~.x”让我失望了。
  • 是的,maninputy 表。 by 指定dat 中的每个FName 对应于maninput 中的xfilter(is.na(y)) 选择列yNA 的数据点,而不是另一个变量。对于您询问的行,您应该了解 across 的作用:dplyr.tidyverse.org/reference/across.html .fns 参数(包含 ~.x)已被指定为“purrr-style lambda”,请参阅此处了解它们是如何工作的:purrr.tidyverse.org/reference/as_mapper.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
  • 2018-03-21
  • 2020-05-28
  • 2019-03-29
  • 1970-01-01
相关资源
最近更新 更多