基于跨两个数据框的日期和条件对行进行子集化

Subsetting rows based on dates and criteria across two data frames

我有一个数据框,概述了从两个地点连续测量的污染水平。

Dates <- as.data.frame(seq(as.Date("2015/01/01"), as.Date("2017/01/01"),"day"))
Pollution_Site.A <- as.data.frame(c(seq(from = 1, to = 366, by = 1),
                       (seq(from = 366, to = 1, by = -1))))
Pollution_Site.B <- as.data.frame(c(seq(from = 0, to = 365, by = 1),
                                (seq(from = 365, to = 0, by = -1))))
df1 <- cbind(Dates,Pollution_Site.A,Pollution_Site.B)
colnames(df1) <- c("Dates","Site.A","Site.B")

我有一个单独的数据框突出显示测量员(每个站点都有一个唯一的测量员)访问每个站点的时间。

Site<- c("Site.A","Site.A","Site.B","Site.B")
Survey_Dates <- as.data.frame(as.POSIXct(c("2014/08/17","2016/08/01",
                                      "2015/02/01","2016/10/31")))
df2 <- as.data.frame(cbind(Site,Survey_Dates))
colnames(df2) <- c("Site","Survey_Dates")

我想要做的是 (i) 定义一个高污染事件(虽然也许某种形式的 'apply' 函数会更好地跨多个站点迭代地执行此操作)?

 High_limit_Site.A <- 1.5*median(df1$Site.A)
 High_limit_Site.B <- 1.5*median(df1$Site.B)

我想 (ii) 对第二个数据框进行子集化,以显示哪些测量员在 1 年内的高污染事件前后访问过该站点(前提是还有污染数据)。我假设 'difftime' 函数中的某些东西可以在这里工作,但我不确定我将如何应用它。

最后,我想要 (iii) 子集数据框来突出显示测量员是在污染事件之前还是之后外出。

所以在上面的示例中,所需的输出应该只包含站点 B。这是因为站点 A 的第一个调查日期早于第一次污染测量并且在高污染事件发生前一年多。在此先感谢您提供的任何帮助。

您需要旋转 df1,然后将其与 df2

交叉连接
library(dplyr)
library(tidyr)

df1 %>% gather(key=Site, value=Pollution, -Dates) %>% 
  group_by(Site) %>% 
  mutate(HighLimit=as.numeric(Pollution>1.5*median(Pollution))) %>% 
  filter(HighLimit==1) %>% 
  # this will function as cross-join because Site is not a unique ID
  left_join(df2, by=c("Site")) %>% 
  mutate(Time_Lag = as.numeric(as.Date(Survey_Dates)-as.Date(Dates)),
         Been_Before = ifelse(Time_Lag>0, "after", "before")) %>% 
  filter(abs(Time_Lag)<365) %>% 
  group_by(Site, Survey_Dates, Been_Before) %>% 
  summarise(Event_date_min=min(Dates), 
            Event_date_max=max(Dates))

在这里你可以看到每次访问对应的最早和最晚的事件

# A tibble: 3 x 5
# Groups:   Site, Survey_Dates [?]
    Site Survey_Dates Been_Before Event_date_min Event_date_max
   <chr>       <dttm>       <chr>         <date>         <date>
1 Site.A   2016-08-01       after     2015-10-03     2016-04-01
2 Site.B   2015-02-01      before     2015-10-02     2016-01-30
3 Site.B   2016-10-31       after     2015-11-01     2016-04-02

只是为了建立上面显示的答案@dmi3kno,然后我可以对每个网站都包含 "before" 和 "after" 标志的网站进行子集化。

Output_df <- df1 %>% gather(key=Site, value=Pollution, -Dates) %>% 
group_by(Site) %>% 
mutate(HighLimit=as.numeric(Pollution>1.5*median(Pollution))) %>% 
filter(HighLimit==1) %>% 
left_join(df2, by=c("Site")) %>% 
mutate(Time_Lag = as.numeric(as.Date(Survey_Dates)-as.Date(Dates)),
     Been_Before = ifelse(Time_Lag>0, "after", "before")) %>% 
filter(abs(Time_Lag)<365) %>% 
group_by(Site, Survey_Dates, Been_Before) %>% 
summarise(Event_date_min=min(Dates), 
        Event_date_max=max(Dates))

然后再次使用 dplyr:

Final_df <- Output_df %>%
group_by(Site) %>%
filter(all(c("before", "after") %in% Been_Before))