r语言 - 如何在日期之间过滤,但保留时间段内未包含的重复项?



我有一个数据集,看起来像这样:

data <- data.frame(group = c("09081997", "13122006", "09081997", "22031969", "09081997"),
date1 = c("2021-08-09", "2021-08-10", "2021-08-21", "2021-07-19", "2021-07-15"))

在"group"变量。例如,我需要在日期"2021-08-01"之间进行过滤。";2021 - 08 - 31 -"。通过这样做,我将"删除"。"group"中的最后两个数字,但我需要保留所有重复的数字,即使它们不在我想要过滤的时间段之间。我需要保留所有的"09081997";寄存器。至少有一个副本必须在该时间段内。

这可能吗?

如果我理解正确,这将工作。我创建了一个辅助变量,按组计数,并且只对只出现一次的组的日期应用过滤器。

library(dplyr)
library(lubridate)
data %>% 
mutate(across(.cols = starts_with("date"),.fns = ymd)) %>% 
add_count(group) %>% 
filter(!(n == 1 & (date1 >= ymd("2021-08-01") & date2 <= ymd("2021-08-31"))))
group      date1      date2 n
1 09081997 2021-08-09 2021-08-31 3
2 09081997 2021-08-21 2021-08-29 3
3 22031969 2021-07-19 2021-07-20 1
4 09081997 2021-07-15 2021-07-19 3

我只是不确定date1和date2应该如何过滤。

使用ave,您可以分组grepl'2021-08'pat术语,并检查是否出现any。由于date*列是字符,我们得到"false"但我们可以很容易地将mode转换为"logical"。最后,我们检查布尔值的rowSums是否大于零,即,如果该行中的两个日期中的任何一个落在'2021-08'中,则产生所需的布尔向量来子集数据帧。

data[with(data, ave(cbind(date1, date2), group, FUN=(x) any(grepl(x, pat='2021-08')))) |> 
`mode<-`('logical') |> rowSums() |> base::`>`(0), ]
#      group      date1      date2
# 1 09081997 2021-08-09 2021-08-31
# 2 13122006 2021-08-10 2021-08-22
# 3 09081997 2021-08-21 2021-08-29
# 5 09081997 2021-07-15 2021-07-19

如果只有一个日期列,则简化为

data1[with(data1, as.logical(ave(date1, group, FUN=(x) any(grepl(x, pat='2021-08'))))), ]
#      group      date1
# 1 09081997 2021-08-09
# 2 13122006 2021-08-10
# 3 09081997 2021-08-21
# 5 09081997 2021-07-15

更新:如果你有一个更复杂的时间段,例如重叠一个月,我们可以使用比较来代替grepl:

data1[with(data1, as.logical(ave(date1, group, FUN=(x) any(
x >= "2021-03-08" | x <= "2021-06-04"
)))), ]


数据:

data <- structure(list(group = c("09081997", "13122006", "09081997", 
"22031969", "09081997"), date1 = c("2021-08-09", "2021-08-10", 
"2021-08-21", "2021-07-19", "2021-07-15"), date2 = c("2021-08-31", 
"2021-08-22", "2021-08-29", "2021-07-20", "2021-07-19")), class = "data.frame", row.names = c(NA, 
-5L))
data1 <- data[1:2]

最新更新