如何将包含每日分辨率的日期时间的数据框更改为半小时分辨率

How to change a dataframe including Date-time with daily resolution to half-hourly resolution

我有一个data.frame喜欢

   WWH        V1        V2        V3        Names
  2018-01-01 0.3240454 0.4044979 0.6208009     a
  2018-01-01 0.7240454 0.6044979 0.9208009     b
  2018-01-01 0.6124702 0.9391351 0.1459288     c
  2018-01-02 0.5754003 0.9088237 0.7105769     a
  2018-01-02 0.6947945 0.1100394 0.4810563     b
  2018-01-02 0.3207489 0.4254129 0.1989616     c

其中Date-time的分辨率是每天。我需要将日期时间的分辨率更改为半小时。所以基本上我需要将每一行重复 48 次,所有列都保持一致,除了第一列将获得同一日期的半小时时间值

  WWH                 V1        V2        V3        Names
  2018-01-01   00:00:00     0.3240454 0.4044979 0.6208009     a
  2018-01-01   00:30:00     0.3240454 0.4044979 0.6208009     a
  2018-01-01   01:00:00     0.3240454 0.4044979 0.6208009     a

。 . .

  2018-01-02   21:30:00     0.3207489 0.4254129 0.1989616     c
  2018-01-02   22:00:00     0.3207489 0.4254129 0.1989616     c
  2018-01-02   22:30:00     0.3207489 0.4254129 0.1989616     c
  2018-01-02   23:00:00     0.3207489 0.4254129 0.1989616     c
  2018-01-02   23:30:00     0.3207489 0.4254129 0.1989616     c

这是可重现的代码

WWH<-seq(as.POSIXlt("2018/1/1"), as.POSIXlt("2018/1/5"), "days")
Names<-c("a","b","c","d","e")
A1<- cbind("Date"=rep(WWH[1],5),as.data.frame(matrix(runif(15),5,3)),"Names"=Names)
A2<-cbind("Date"=rep(WWH[2],3),as.data.frame(matrix(runif(9),3,3)),"Names"=Names[1:3])
A3<-cbind("Date"=rep(WWH[3],2),as.data.frame(matrix(runif(2),2,3)),"Names"=Names[4:5])
df<-rbind(A1,A2,A3)

这是一个使用 rep()seq() 两个步骤的解决方案。

数据:

WWH<-seq(as.POSIXlt("2018/1/1"), as.POSIXlt("2018/1/5"), "days")
Names<-c("a","e","r","c","u")
df <- cbind(WWH,as.data.frame(matrix(runif(15),5,3)),Names)

首先,我们将数据帧的所有行克隆 48 次,占 48 个半小时。

df.exp <- df[rep(row.names(df), each = 48), ]

然后我们用半小时的序列替换WWH,从第一天开始,到最后一天的23:30结束:

df.exp$WWH <- seq(
  from=df$WWH[1],
  to=df$WWH[nrow(df)] + 84600,
  by=1800
)

结果:

> head(df.exp)
                    WWH       V1         V2        V3 Names
1   2018-01-01 00:00:00 0.639078 0.01123183 0.4661781     a
1.1 2018-01-01 00:30:00 0.639078 0.01123183 0.4661781     a
1.2 2018-01-01 01:00:00 0.639078 0.01123183 0.4661781     a
1.3 2018-01-01 01:30:00 0.639078 0.01123183 0.4661781     a
1.4 2018-01-01 02:00:00 0.639078 0.01123183 0.4661781     a
1.5 2018-01-01 02:30:00 0.639078 0.01123183 0.4661781     a

> tail(df.exp)
                     WWH        V1        V2        V3 Names
5.42 2018-01-05 21:00:00 0.1457907 0.5508916 0.7658603     u
5.43 2018-01-05 21:30:00 0.1457907 0.5508916 0.7658603     u
5.44 2018-01-05 22:00:00 0.1457907 0.5508916 0.7658603     u
5.45 2018-01-05 22:30:00 0.1457907 0.5508916 0.7658603     u
5.46 2018-01-05 23:00:00 0.1457907 0.5508916 0.7658603     u
5.47 2018-01-05 23:30:00 0.1457907 0.5508916 0.7658603     u

参考书目:

Replicate each row of data.frame and specify the number of replications for each row

Create a time series by 30 minute intervals

How to subtract/add days from/to a date?


编辑:这是使用 interaction 创建分组变量的 dplyr 版本:

WWH<-seq(as.POSIXlt("2018/1/1"), as.POSIXlt("2018/1/5"), "days")
Names<-c("a","b","c","d","e")
A1<- cbind("Date"=rep(WWH[1],5),as.data.frame(matrix(runif(15),5,3)),"Names"=Names)
A2<-cbind("Date"=rep(WWH[2],3),as.data.frame(matrix(runif(9),3,3)),"Names"=Names[1:3])
A3<-cbind("Date"=rep(WWH[3],2),as.data.frame(matrix(runif(2),2,3)),"Names"=Names[4:5])
df<-rbind(A1,A2,A3)

df.exp <- df[rep(row.names(df), each = 48), ]

  df.exp <- df.exp %>%
  mutate(temp = droplevels(interaction(df.exp$Date, df.exp$Names))) %>%
  group_by(temp) %>%
  mutate(Datetime = seq(
    from = unique(Date),
    to = unique(Date) + 84600,
    by = 1800
  )) %>%
  ungroup() %>%
  select(-(temp))

tail(df.exp)

# A tibble: 6 x 6
        Date        V1        V2        V3  Names            Datetime
      <dttm>     <dbl>     <dbl>     <dbl> <fctr>              <dttm>
1 2018-01-03 0.4327316 0.4327316 0.4327316      e 2018-01-03 21:00:00
2 2018-01-03 0.4327316 0.4327316 0.4327316      e 2018-01-03 21:30:00
3 2018-01-03 0.4327316 0.4327316 0.4327316      e 2018-01-03 22:00:00
4 2018-01-03 0.4327316 0.4327316 0.4327316      e 2018-01-03 22:30:00
5 2018-01-03 0.4327316 0.4327316 0.4327316      e 2018-01-03 23:00:00
6 2018-01-03 0.4327316 0.4327316 0.4327316      e 2018-01-03 23:30:00