【问题标题】:Add rows with dates till January next year添加日期到明年 1 月的行
【发布时间】:2019-01-21 08:36:34
【问题描述】:

我确实有相当复杂的案例需要我解决。让我通过一个例子来解释你..所以我们从下表开始:

 Datum Urlaub_geplannt
1 2018-10            1410
2 2018-11             940
3 2018-12             470


structure(list(Datum = structure(1:3, .Label = c("2018-10", "2018-11", 
"2018-12"), class = "factor"), Urlaub_geplannt = c(1410, 940, 
470)), .Names = c("Datum", "Urlaub_geplannt"), row.names = c(NA, 
-3L), class = "data.frame")

我希望在明年 1 月之前将新行添加到此表中(基准列),并且所有其他列都应填充为 0。在这种情况下,最终表应如下所示:

 Datum Urlaub_geplannt
1 2018-10            1410
2 2018-11             940
3 2018-12             470
4 2019-01             0

但是,随着我的数据发生变化(实际上是在Shiny 中),以某种方式自动使其成为“年末”非常重要。

我的意思是,如果我有来自 2019 年的行的新数据,我希望自动获得“结束日期”为 2020 年 1 月。感谢您的帮助!

【问题讨论】:

  • 每个月需要一行吗?
  • 是的,直到明年 1 月,我确实每个月都需要一行

标签: r


【解决方案1】:

基本 R 方法

get_date_till_Jan <- function(df) {
  #Convert the character dates to actual Date objects
  max_Date <- max(as.Date(paste0(df$Datum, "-01")))

  #Get the date for next year January
  next_Jan <- as.Date(paste0(as.numeric(format(max_Date, "%Y")) + 1, "-01-01"))

  #Create a monthly sequence from the max date to next Jan date
  new_date <- format(seq(max_Date, next_Jan, by = "month")[-1], "%Y-%m")

  #Create a new dataframe with all values as 0 and change only the Datum 
  #column with new_date and rbind it to original dataframe
  rbind(df, transform(data.frame(matrix(0, nrow = length(new_date), 
      ncol = ncol(df), dimnames = list(NULL, names(df)))), 
      Datum = new_date))
}

df <- get_date_till_Jan(df)
df

#    Datum Urlaub_geplannt
#1 2018-10            1410
#2 2018-11             940
#3 2018-12             470
#4 2019-01               0

这适用于任意数量的列

df['another_col'] = 1:4
get_date_till_Jan(df)


#     Datum Urlaub_geplannt another_col
#1  2018-10            1410           1
#2  2018-11             940           2
#3  2018-12             470           3
#4  2019-01               0           4
#5  2019-02               0           0
#6  2019-03               0           0
#7  2019-04               0           0
#8  2019-05               0           0
#9  2019-06               0           0
#10 2019-07               0           0
#11 2019-08               0           0
#12 2019-09               0           0
#13 2019-10               0           0
#14 2019-11               0           0
#15 2019-12               0           0
#16 2020-01               0           0

【讨论】:

    【解决方案2】:

    dplyrfull_join 的解决方案:

    library(dplyr)
    library(lubridate) # for ymd() function
    
    
    d <- d %>% 
      mutate(Datum = paste0(Datum,"-01"),
             Datum = ymd(Datum)) # correct Date format
    
    min_year <- year(min(d$Datum))
    min_date <- min(d$Datum)
    
    # create a data.frame of possible dates
    fill_dates <- data.frame(Datum = seq.Date(
      min_date, # min date avaiable
      as.Date(paste0(min_year+1,"-01-01")), # until first Jan next year
      by = "month"))
    

    现在我们可以加入两个data.frames

    d %>% 
      full_join(fill_dates, by="Datum") %>% # full_join of the two tables
      # the full_join will add all new row not present in d originally, with NA
      mutate(Urlaub_geplannt = ifelse(is.na(Urlaub_geplannt), 0, Urlaub_geplannt))
    
    #       Datum Urlaub_geplannt
    # 1 2018-10-01            1410
    # 2 2018-11-01             940
    # 3 2018-12-01             470
    # 4 2019-01-01               0
    

    数据:

    d <- structure(list(Datum = structure(c("2018-10", "2018-11", 
                                                          "2018-12"), class = "character"), Urlaub_geplannt = c(1410, 940, 
                                                                                                             470)), .Names = c("Datum", "Urlaub_geplannt"), row.names = c(NA, 
                                                                                                                                                                          -3L), class = "data.frame")
    

    【讨论】:

      【解决方案3】:
      df <- structure(list(Datum = structure(1:3, .Label = c("2018-10", "2018-11", 
                                                             "2018-12"), class = "factor"), Urlaub_geplannt = c(1410, 940, 
                                                                                                                470)), .Names = c("Datum", "Urlaub_geplannt"), row.names = c(NA, 
                                                                                                                                                                             -3L), class = "data.frame")
      
      
      
      
      Datum <- format(seq.Date(as.Date(paste0(df$Datum[nrow(df)],"-01")),
                               as.Date(paste0(substring(seq.Date(as.Date(paste0(as.character(df$Datum[1]),"-01")), 
                                                                 length = 2,
                                                                 by = 'year')[2],1,4),"-01-01")),
                               by = "month"
      
      ),"%Y-%m")
      
      
      new_df <- data.frame(Datum  = Datum, Urlaub_geplannt = rep(0,length(Datum)))
      
      
      total_df <- rbind(df,new_df)
      
      total_df
      #>     Datum Urlaub_geplannt
      #> 1 2018-10            1410
      #> 2 2018-11             940
      #> 3 2018-12             470
      #> 4 2018-12               0
      #> 5 2019-01               0
      

      【讨论】:

      • 感谢您的回答!但是我想在表格的基础上自动检查“max”/“end”年份
      • 所以您不想根据 2018 年自动检测 2020-01
      • 我想先检查表中的数据是从什么日期(年份)开始,然后自动创建新行,直到明年一月。因此,如果我的数据是表中 2018 年的数据,那么我需要行到 2019 年 1 月,等等。应将具有日期序列的行添加到现有的表中,并且所有其他列都应填充 0!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-13
      • 2014-08-20
      • 2013-07-14
      • 2011-04-01
      • 1970-01-01
      • 2018-07-25
      • 1970-01-01
      相关资源
      最近更新 更多