簡體   English   中英

通過向日期列添加一系列月份來創建新列

[英]Create new columns by adding a sequence of months to a date column

我有日期列的數據:

library(data.table)
library(lubridate)

Y = data.table(X = c("2012-12-31", "2021-10-31"))

            X  
1: 2012-12-31
2: 2021-10-31                    

我想添加一系列月份,從 1 到x到“X”列中的日期。 結果應該是一組新列,“X_1”、“X_2”、...“X_x”:

            X          X_1          X_2    X_x
1: 2012-12-31   2013-01-31   2013-02-28 .. (2012-12-31) %m+% months(x)
2: 2021-10-31   2021-11-30   2021-12-31 .. (2021-10-31) %m+% months(x)

我嘗試了幾件沒有用的事情,例如:

  Y[ , c(paste0("X_", 1:15))] = AddMonths(Y$X, c(1:15)) %>% LastDayInMonth()
  Y[ , c(paste0("X_", 1:15)) := AddMonths(as.IDate(X), c(1:15)) %>% LastDayInMonth()]

我想根據這個操作創建 15 列,所以我想避免for循環。 我的真實數據有 80K 行。

%m+%months都是向量化的。

library(data.table)
library(lubridate)

n = 3 
nm = paste0("x", "_", seq(n))
m = rep(seq(n), each = nrow(d))
d[ , (nm) := split(x %m+% months(m), m)]
d
#             x        x_1        x_2        x_3
# 1: 2012-12-31 2013-01-31 2013-02-28 2013-03-31
# 2: 2021-10-31 2021-11-30 2021-12-31 2022-01-31

解釋

設置要添加到日期列中每個值的序列中的最大月數(例如n = 3 )。 創建應將結果分配給的列名向量 ( nm = paste0("x", "_", seq(n)) )。 創建要添加 ( m = rep(seq(n), each = nrow(d)) ) 到日期列的月份向量。 將 'm' 中的月份添加到 'x' 中的日期 ( x %m+% months(m) )。 按添加到列表的月數 ( split(x %m+% months(m), m) ) 拆分結果。 使用data.table的基本屬性,“列表的每個元素成為結果data.table中的一列”,並通過引用 ( := ) 分配結果列。


d = data.table(x = as.Date(c("2012-12-31","2021-10-31")))

更新:我粘貼了錯誤版本的答案: months(1)應該是months(i-1) 現在更正了。

在 for 循環中,我們可以這樣做:

library(lubridate) #%m+%
Y=data.table("X"=as.Date(c("2012-12-31","2021-10-31")))

for (i in 2:15) {
  Y <- Y %>% 
    mutate(col= X %m+% months(i-1))
  colnames(Y)[i] <- paste0("X_",i-1)
}
 X        X_1        X_2        X_3        X_4        X_5        X_6        X_7        X_8        X_9       X_10       X_11       X_12
1: 2012-12-31 2013-01-31 2013-02-28 2013-03-31 2013-04-30 2013-05-31 2013-06-30 2013-07-31 2013-08-31 2013-09-30 2013-10-31 2013-11-30 2013-12-31
2: 2021-10-31 2021-11-30 2021-12-31 2022-01-31 2022-02-28 2022-03-31 2022-04-30 2022-05-31 2022-06-30 2022-07-31 2022-08-31 2022-09-30 2022-10-31
         X_13       X_14
1: 2014-01-31 2014-02-28
2: 2022-11-30 2022-12-31

由於問題被標記為dplyr我認為tidyverse也是允許的。

從您擁有的 2 個日期的列表開始。

date作為輸入的 function 從起始月份開始添加與在附加參數中選擇的月份一樣多的月份。

然后將 function 與map一起應用於初始日期列表。 然后將其轉換為data.frame

  • 示例僅顯示n=6
  • 包含循環
library(tidyverse)
library(lubridate)

f <- function(x, n = 5) {
  yy <- x
  for (i in seq(n)) {
    yy <- append(yy, x %m+% months(i))
  }
  return(yy)
}

l <- list(("2012-12-31"), ("2021-10-31"))
l |>
  map(lubridate::as_date) |>
  map(n = 6, f) |>
  as.data.frame() |>
  setNames(l) |>
  t() |> as.data.frame()
#>                    V1         V2         V3         V4         V5         V6
#> 2012-12-31 2012-12-31 2013-01-31 2013-02-28 2013-03-31 2013-04-30 2013-05-31
#> 2021-10-31 2021-10-31 2021-11-30 2021-12-31 2022-01-31 2022-02-28 2022-03-31
#>                    V7
#> 2012-12-31 2013-06-30
#> 2021-10-31 2022-04-30

請檢查此代碼

data.table("X"=c("2012-12-31","2021-10-31")) %>% mutate(date=as.Date(X), seq=row_number(), date2=date %m+% months(15)) %>% 
  group_by(seq) %>% 
  pivot_longer(starts_with('date'), names_to = 'name', values_to = 'date') %>% 
  tidyr::complete(date=full_seq(date, period = 1)) %>% fill(X) %>% 
  mutate(year=year(date), month=month(date)) %>% group_by(X,year, month) %>% 
  slice_tail(n=1) %>% ungroup %>% group_by(X) %>%
  mutate(row=row_number()) %>% 
  pivot_wider(X,names_from = row, names_prefix = 'X',values_from = date)

創建於 2023-01-28,使用reprex v2.0.2

# A tibble: 2 × 17
# Groups:   X [2]
  X          X1         X2         X3         X4         X5         X6         X7         X8         X9         X10        X11       
  <chr>      <date>     <date>     <date>     <date>     <date>     <date>     <date>     <date>     <date>     <date>     <date>    
1 2012-12-31 2012-12-31 2013-01-31 2013-02-28 2013-03-31 2013-04-30 2013-05-31 2013-06-30 2013-07-31 2013-08-31 2013-09-30 2013-10-31
2 2021-10-31 2021-10-31 2021-11-30 2021-12-31 2022-01-31 2022-02-28 2022-03-31 2022-04-30 2022-05-31 2022-06-30 2022-07-31 2022-08-31
# … with 5 more variables: X12 <date>, X13 <date>, X14 <date>, X15 <date>, X16 <date>
# ℹ Use `colnames()` to see all variable names

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM