2

我有 10 个站点,有 15 年的每小时降雨数据。所有人都有几个小时,甚至几天在他们的系列中随机跳跃。我希望将 15 年期间的所有每小时时间步长用作索引,然后将所有站点数据组合到一个数据帧中,同时为每个站点的跳跃提供 NA(甚至某些邻居的平均值)。那么在R中有什么建议吗?

例如我有数据框雨量_1

date                       station210
1994-01-01 00:00:00 0
1994-01-01 02:00:00 0
1994-01-01 03:00:00 0
1994-01-01 04:00:00 0.6
1994-01-01 06:00:00 2.6
1994-01-01 07:00:00 3.2

第二站是rainbow_2

date                      station212
1994-01-01 00:00:00 0
1994-01-01 01:00:00 1.8
1994-01-01 02:00:00 1.8
1994-01-01 03:00:00 1.8
1994-01-01 04:00:00 1.4
1994-01-01 06:00:00 1.8

当我尝试

merge(rainfall_1, rainfall_2, all=TRUE)
date               station_210  station_212
1994-01-01 00:00:00 0.0 0.0
1994-01-01 02:00:00 0.0 1.8
1994-01-01 03:00:00 0.0 1.8
1994-01-01 04:00:00 0.6 1.4
1994-01-01 06:00:00 2.6 1.8 

一些问题是它确实错过了第二个数据帧的第二行(rainfall_2),并且错过了第 5 小时的值,这两个数据帧中都不存在。我正在寻找一个解决方案,其中包括第二个时间步长(2 小时)并且是 NA 或其邻居的平均值,以及第 5 小时时间步长以给出两者的 NA 或邻居的平均值。

想象一下,如果您有这些时间序列数据是针对许多站点的数千个,其中一些随机间隔丢失。

4

2 回答 2

0

假设rainfall_1rainfall_2具有 POSIXctdate列。现在,将数据帧转换为 zoo 对象,并将第三个 zoo 对象z3(等于z2)添加到示例中,以显示其不限于两个输入。合并所有三个(动物园的合并处理多路合并)zz,然后将合并的时间序列与零宽度网格合并,z0.

library(zoo)

# set up input zoo objects
z1 <- read.zoo(rainfall_1, FUN = identity)
z2 <- read.zoo(rainfall_2, FUN = identity)
z3 <- z2

zz <- merge(z1, z2, z3)
z0 <- zoo(, seq(start(zz), end(zz), by = "hour"))
zout <- merge(zz, z0)

这给出了:

> zout
                     z1  z2  z3
1994-01-01 00:00:00 0.0 0.0 0.0
1994-01-01 01:00:00  NA 1.8 1.8
1994-01-01 02:00:00 0.0 1.8 1.8
1994-01-01 03:00:00 0.0 1.8 1.8
1994-01-01 04:00:00 0.6 1.4 1.4
1994-01-01 05:00:00  NA  NA  NA
1994-01-01 06:00:00 2.6 1.8 1.8
1994-01-01 07:00:00 3.2  NA  NA

您可能希望将其留在动物园中以利用其其他设施,但如果您确实想将其转回数据框:

library(ggplot2)
dfout <- fortify(zout)
于 2013-06-28T12:14:15.493 回答
0

我认为这可能会做你想要的。我不确定为什么最终合并的数据集从 12 月 31 日下午 3:00 开始,而不是 1 月 1 日午夜开始。我怀疑这与我的计算机相对于 GMT 的时钟有关。

df.1 <- read.table(text = '
date       time     station210
1994-01-01 00:00:00 0
1994-01-01 02:00:00 0
1994-01-01 03:00:00 0
1994-01-01 04:00:00 0.6
1994-01-01 06:00:00 2.6
1994-01-01 07:00:00 3.2
', header = TRUE, stringsAsFactors=FALSE)

df.2 <- read.table(text = '
 date       time    station212
1994-01-01 00:00:00 0
1994-01-01 01:00:00 1.8
1994-01-01 02:00:00 1.8
1994-01-01 03:00:00 1.8
1994-01-01 04:00:00 1.4
1994-01-01 06:00:00 1.8
', header=TRUE, stringsAsFactors=FALSE)

cols <- c( 'date' , 'time' )

df.1$datetime <- apply( df.1[ , cols ] , 1 , paste , collapse = " " )
df.2$datetime <- apply( df.2[ , cols ] , 1 , paste , collapse = " " )

df.1 <- df.1[, c('datetime', 'station210')]
df.2 <- df.2[, c('datetime', 'station212')]

df.3 <- merge(df.1, df.2, by="datetime", all=TRUE)

df.3[order(df.3$datetime),]

df.3$datetime <- format(as.POSIXct(df.3$datetime, format = "%Y-%m-%d %H:%M:%S"),  "%Y-%m-%d %H:%M:%S" )
df.3

hour <- seq(0,60*60*24,by=60*60)

datetime <- as.POSIXlt(hour, origin="1994-01-01")

datetime <-  format( as.POSIXct(hour, origin="1994-01-01"), "%Y-%m-%d %H:%M:%S"  )

newdf <- merge(data.frame(datetime), df.3, all.x=TRUE, by="datetime")
newdf

              datetime station210 station212
1  1993-12-31 15:00:00         NA         NA
2  1993-12-31 16:00:00         NA         NA
3  1993-12-31 17:00:00         NA         NA
4  1993-12-31 18:00:00         NA         NA
5  1993-12-31 19:00:00         NA         NA
6  1993-12-31 20:00:00         NA         NA
7  1993-12-31 21:00:00         NA         NA
8  1993-12-31 22:00:00         NA         NA
9  1993-12-31 23:00:00         NA         NA
10 1994-01-01 00:00:00        0.0        0.0
11 1994-01-01 01:00:00         NA        1.8
12 1994-01-01 02:00:00        0.0        1.8
13 1994-01-01 03:00:00        0.0        1.8
14 1994-01-01 04:00:00        0.6        1.4
15 1994-01-01 05:00:00         NA         NA
16 1994-01-01 06:00:00        2.6        1.8
17 1994-01-01 07:00:00        3.2         NA
18 1994-01-01 08:00:00         NA         NA
19 1994-01-01 09:00:00         NA         NA
20 1994-01-01 10:00:00         NA         NA
21 1994-01-01 11:00:00         NA         NA
22 1994-01-01 12:00:00         NA         NA
23 1994-01-01 13:00:00         NA         NA
24 1994-01-01 14:00:00         NA         NA
25 1994-01-01 15:00:00         NA         NA

编辑 - 2013 年 7 月 6 日

这是处理两个以上数据帧的一种方法。

以下是数据:

df.1 <- read.table(text = '
date       time     station210
1994-01-01 00:00:00 0
1994-01-01 02:00:00 0
1994-01-01 03:00:00 0
1994-01-01 04:00:00 0.6
1994-01-01 06:00:00 2.6
1994-01-01 07:00:00 3.2
', header = TRUE, stringsAsFactors=FALSE)

df.2 <- read.table(text = '
 date       time    station212
1994-01-01 00:00:00 0
1994-01-01 01:00:00 1.8
1994-01-01 02:00:00 1.8
1994-01-01 03:00:00 1.8
1994-01-01 04:00:00 1.4
1994-01-01 06:00:00 1.8
', header=TRUE, stringsAsFactors=FALSE)

df.3 <- read.table(text = '
 date       time    station214
1993-12-31 22:00:00 5.0
1993-12-31 23:00:00 2.0
1994-01-01 02:00:00 1.0
1994-01-01 04:00:00 3.0
1994-01-01 06:00:00 5.0
1994-01-01 08:00:00 4.0
', header=TRUE, stringsAsFactors=FALSE)

创建数据框列表并创建变量datetime

my.data <- sapply(paste('df.', seq(1,3,1), sep=''), get, environment(), simplify = FALSE) 

date.time <- function(x) { 
                      cols <- c( 'date' , 'time' )
                      x$datetime <- apply( x[ , cols ] , 1 , paste , collapse = " " )
                      x <- x[, 3:4]
                      return(x)
             }

my.list <- lapply(my.data, function(x) date.time(x))

合并和排序该列表中的数据框:

df.3 <- Reduce(function(...) merge(..., all=T), my.list)
df.3[order(df.3$datetime),]

将缺失的日期和时间添加到合并的数据框中:

df.3$datetime <- format(as.POSIXct(df.3$datetime, format = "%Y-%m-%d %H:%M:%S"),  "%Y-%m-%d %H:%M:%S" )

hour <- seq(0,60*60*24,by=60*60)

datetime <- as.POSIXlt(hour, origin="1994-01-01")

datetime <-  format( as.POSIXct(hour, origin="1994-01-01"), "%Y-%m-%d %H:%M:%S"  )

newdf <- merge(data.frame(datetime), df.3, all.x=TRUE, by="datetime")
newdf

这是用来自同一站点的前后观测值的平均值替换来自站点的缺失观测值的代码。我正在使用for-loops可能非常低效的嵌套。如果我想出一种更有效的方法,我会尽量记住把它贴在这里。如果你的数据集很大,这些嵌套for-loops可能需要很长时间才能运行。

newdf2 <- newdf

for(i in 1:nrow(newdf)) {
     for(j in 2:ncol(newdf)) {

          if(i == 1 &                   is.na(newdf[i,j]))  newdf2[i,j] = newdf[i+1,j]
          if(i ==         nrow(newdf) & is.na(newdf[i,j]))  newdf2[i,j] = newdf[i-1,j]
          if(i >  1 & i < nrow(newdf) & is.na(newdf[i,j]))  newdf2[i,j] = mean(c(newdf[i-1,j], newdf[i+1,j]), na.rm=TRUE) 
          if(is.nan(newdf2[i,j]))                           newdf2[i,j] = NA

     }
}

cbind(newdf, newdf2)
于 2013-06-28T09:24:11.043 回答