我有10个站点,每小时有15年的降雨量数据。所有人都有几个小时甚至几天随机跳跃。我希望将15年持续时间的所有小时时间步长用作索引,然后将所有站数据组合到一个数据帧,同时给每个站的跳转提供NA(或甚至一些邻居的平均值)。所以在 R 中有任何建议吗?
例如我有数据帧rainfall_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
第二站是降雨量
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或平均值。
想象一下,如果你有这些时间序列数据,那么对于许多电台而言,这些时间序列的数据会随机丢失。
答案 0 :(得分:0)
我认为这可能会做你想要的。我不确定为什么最终的合并数据集从12月31日下午3点开始,而不是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)
答案 1 :(得分:0)
假设rainfall_1
和rainfall_2
有POSIXct date
列。现在,将数据帧转换为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)