从数据框中删除不完整的月份,即使月份的一部分包含数据
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 匹配的第一个日期,使用 which
和 tail
到 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
我想从我的数据框中删除不完整的月份,即使有些月份有数据。
示例数据框:
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 匹配的第一个日期,使用 which
和 tail
到 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