r语言 - 从数据框中删除不完整的月份,即使该月的一部分包含数据也是如此



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

示例数据框:

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)

如果我正确解释了您的问题,您希望能够选择具有完整天数的月份,删除那些没有天数的月份。

以下用途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生成仅包含完整月份的数据集。

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

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

在基本 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 得到一个月的第一天和一个月的最后一天。这返回

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

现在,使用 which.max 选择匹配的第一个日期,并使用 tail which选择与每月序列匹配的最后一天,以便找出 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)

现在,对您的数据帧进行子集化

dfNew <- df[startRow:stopRow,]
range(dfNew$date)
[1] "2016-02-01" "2016-08-31"
nrow(dfNew)
[1] 213

最新更新