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

时间:2018-08-06 07:55:39

标签: r datetime dataframe posixlt

我有一个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

,其中“日期时间”的分辨率为每天。我需要将日期时间的分辨率更改为半小时。因此,基本上我需要将每一行重复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)

1 个答案:

答案 0 :(得分:1)

这是一个使用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?


编辑:以下是dplyr版本,使用interaction创建分组变量:

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