【问题标题】:Remove incomplete months from a data frame even when part of the month contains data从数据框中删除不完整的月份,即使月份的一部分包含数据
【发布时间】:2017-06-22 19:44:30
【问题描述】:

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

示例数据框:

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)

【问题讨论】:

    标签: r data-management


    【解决方案1】:

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

    以下使用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 只需完整的几个月即可生成您的数据集。

    【讨论】:

      【解决方案2】:

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

      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
      

      【讨论】:

      • 将您的代码应用于我的“真实”数据集时出现以下错误:Error in min(df$date) - 31 : non-numeric argument to binary operator。这与日期的格式有关吗?
      • 如果您的日期是字符格式而不是日期格式(日期格式实际上是一种附加了 Date 类的数字格式),那么您会收到错误消息。
      【解决方案3】:

      在基础 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 选择第一个匹配的日期,使用whichtail 选择与每月序列匹配的最后一天,以便确定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
      

      【讨论】:

        猜你喜欢
        • 2021-10-11
        • 1970-01-01
        • 2020-11-21
        • 2021-03-24
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 2012-02-02
        • 2019-09-21
        相关资源
        最近更新 更多