从数据框中删除不完整的月份,即使月份的一部分包含数据

Remove incomplete months from a data frame even when part of the month contains data

我想从我的数据框中删除不完整的月份,即使有些月份有数据。

示例数据框:

date <- seq.Date(as.Date("2016-01-15"),as.Date("2016-09-19"),by="day")
data <- seq(1:249)

df <- data.frame(date,data)

我想要什么:

date2 <- seq.Date(as.Date("2016-02-01"),as.Date("2016-08-31"),by="day")
data2 <- seq(from = 18, to = 230)

df2 <- data.frame(date2,data2)

您可以将每个月的一组完整日期连接到您的数据框,然后过滤掉具有任何缺失值的月份。

library(tidyverse)
library(lubridate)

df.filtered = data.frame(date=seq(min(df$date)-31,max(df$date)+31,by="day")) %>%
  left_join(df) %>%
  group_by(month=month(date)) %>%   # Add a month column and group by it
  filter(!any(is.na(data))) %>%     # Remove months with any missing data
  ungroup %>%                       
  select(-month)                    # Remove the month column

# A tibble: 213 x 2
         date  data
       <date> <int>
 1 2016-02-01    18
 2 2016-02-02    19
 3 2016-02-03    20
 4 2016-02-04    21
 5 2016-02-05    22
 6 2016-02-06    23
 7 2016-02-07    24
 8 2016-02-08    25
 9 2016-02-09    26
10 2016-02-10    27
# ... with 203 more rows

如果我对你的问题的解释正确,你希望能够 select 有 完整天数 的月份,删除没有的月份。

以下使用dplyr v0.7.0:

library(dplyr)

df <- df %>%
  mutate(mo = months(date)) # add month (mo)

complete_mo <- df %>%
  count(mo) %>% #count number of days in month (n)
  filter(n >= 28) %>% #rule of thumb definition of a `complete month`
  pull(mo)

df_complete_mo <- df %>%
  filter(mo %in% complete_mo) %>% # here is where you select the complete months
  select(-mo) #remove mo, to keep your original df

然后 df_complete_mo 只需要 整月 .

就可以生成您的数据集

在基础 R 中,您可以执行以下操作。

# get start and end dates of months that are are beyond the sample
dateRange <- as.Date(format(range(df$date) + c(-32, 32), c("%Y-%m-2", "%Y-%m-1"))) - 1

format 的第二个参数是一个向量,它分别格式化最小和最大日期。我们从这些日期中减去 1 以获得一个月的第一天和一个月的最后一天。这个returns

dateRange
[1] "2015-12-01" "2016-09-30"

现在,使用 which.max 到 select 匹配的第一个日期,使用 whichtail 到 select 匹配每月序列的最后一天为了弄清楚 data.frame.

的开始行和停止行
startRow <- which.max(df$date %in% seq(dateRange[1], dateRange[2], by="month"))
stopRow <- tail(which(df$date %in% (seq(dateRange[1], dateRange[2], by="month")-1)), 1)

现在,子集你的 data.frame

dfNew <- df[startRow:stopRow,]

range(dfNew$date)
[1] "2016-02-01" "2016-08-31"
nrow(dfNew)
[1] 213