R语言 通过向日期列添加月份序列来创建新列

ruarlubt  于 2023-02-01  发布在  其他
关注(0)|答案(4)|浏览(122)

我的数据包含日期列:

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

我想给“X”列中的日期添加一个月份序列,从1到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行。

jvlzgdj9

jvlzgdj91#

%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))。将结果除以添加的月数使用data.table的基本属性"* 列表中的每个元素都成为结果data.table * 中的一列",并通过引用(:=)指定结果列。

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

uqdfh47h2#

由于问题标记为dplyr,我假设tidyverse也是允许的。
从你的两个约会开始。
date为输入的函数从开始月份添加附加参数中选择的月份数。
然后,该函数与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
im9ewurl

im9ewurl3#

请检查此代码

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年1月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
pdtvr36n

pdtvr36n4#

**更新:**我粘贴了错误版本的答案: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

相关问题