r 中重复时间的平均网格化气候数据
average gridded climate data for duplicated times in r
我有一个网格气候数据集,例如:
# generate time vector
time1 <- seq(14847.5,14974.5, by = 1)
time2 <- seq(14947.5,14974.5, by = 1)
time <- c(time1,time2)
time <- as.POSIXct(time*86400,origin='1970-01-01 00:00')
# generate lat and lon coordinates
lat <- seq(80,90, by = 1)
lon <- seq(20,30, by = 1)
# generate 3dimensional array
dat <- array(runif(length(lat)*length(lon)*length(time)),
dim = c(length(lon),length(lat),length(time)))
这样
> dim(dat)
[1] 11 11 156
数据的维度描述了不同经度(dim = 1
)、纬度(dim = 2
)和时间(dim = 3
)的变量。
我目前遇到的问题是某些时间重复,这与测量数据的重叠传感器有关。因此,我想知道是否可以只保留 dat
的唯一时间,但对重复时间的网格内数据进行平均,即如果有两天重复,我们取每个纬度和经度的平均值当时的网格。
我可以找到唯一时间为:
# only select unique times
new_time <- unique(time)
unique_time <- unique(time)
下面的代码旨在遍历每个网格 (lat
/lon
) 并对所有重复的天数进行平均。
# loop through lat/lon coordinates to generate new data
new_dat <- array(dim = c(length(lon),length(lat),length(new_time)))
for(i in 1:length(lon)){
for(ii in 1:length(lat)){
dat2 <- dat[i,ii,]
dat2b <- NA
for(k in 1:length(unique_time)){
idx <- time == unique_time[k]
dat2b[k] <- mean(dat2[idx], na.rm = TRUE)
}
new_dat[i,ii,] <- dat2b
}
}
我确信这提供了正确的答案,但我确信有一种更简洁的方法可以实现这一点。
我还应该注意到我的数据非常大(即 k = 7000
),所以至少可以说最后一个循环不是很有效。
我原来的回答:
使用aggregate
更简洁高效:
for(i in 1:length(lon)){
for(ii in 1:length(lat)){
new_dat[i,ii,] <- as.numeric(aggregate(dat[i,ii,], by=list(time),mean)$x)
}
}
它仍然有 3 个循环中的 2 个,但它设法绕过了创建 dat2
、dat2b
和 unique_time
。
我的改进答案:
f <- function(i, ii){as.numeric(aggregate(dat[i,ii,], by=list(time),mean)$x)}
for(i in 1:nrow(expand.grid(1:length(lon),1:length(lat)))){
new_dat[expand.grid(1:length(lon),1:length(lat))[i,1],
expand.grid(1:length(lon),1:length(lat))[i,2],] <-
f(expand.grid(1:length(lon),1:length(lat))[i,1],expand.grid(1:length(lon),
1:length(lat))[i,2])
}
减少到只有 1 个循环。我们也可以使用 apply
.
绕过该循环
我有一个网格气候数据集,例如:
# generate time vector
time1 <- seq(14847.5,14974.5, by = 1)
time2 <- seq(14947.5,14974.5, by = 1)
time <- c(time1,time2)
time <- as.POSIXct(time*86400,origin='1970-01-01 00:00')
# generate lat and lon coordinates
lat <- seq(80,90, by = 1)
lon <- seq(20,30, by = 1)
# generate 3dimensional array
dat <- array(runif(length(lat)*length(lon)*length(time)),
dim = c(length(lon),length(lat),length(time)))
这样
> dim(dat)
[1] 11 11 156
数据的维度描述了不同经度(dim = 1
)、纬度(dim = 2
)和时间(dim = 3
)的变量。
我目前遇到的问题是某些时间重复,这与测量数据的重叠传感器有关。因此,我想知道是否可以只保留 dat
的唯一时间,但对重复时间的网格内数据进行平均,即如果有两天重复,我们取每个纬度和经度的平均值当时的网格。
我可以找到唯一时间为:
# only select unique times
new_time <- unique(time)
unique_time <- unique(time)
下面的代码旨在遍历每个网格 (lat
/lon
) 并对所有重复的天数进行平均。
# loop through lat/lon coordinates to generate new data
new_dat <- array(dim = c(length(lon),length(lat),length(new_time)))
for(i in 1:length(lon)){
for(ii in 1:length(lat)){
dat2 <- dat[i,ii,]
dat2b <- NA
for(k in 1:length(unique_time)){
idx <- time == unique_time[k]
dat2b[k] <- mean(dat2[idx], na.rm = TRUE)
}
new_dat[i,ii,] <- dat2b
}
}
我确信这提供了正确的答案,但我确信有一种更简洁的方法可以实现这一点。
我还应该注意到我的数据非常大(即 k = 7000
),所以至少可以说最后一个循环不是很有效。
我原来的回答:
使用aggregate
更简洁高效:
for(i in 1:length(lon)){
for(ii in 1:length(lat)){
new_dat[i,ii,] <- as.numeric(aggregate(dat[i,ii,], by=list(time),mean)$x)
}
}
它仍然有 3 个循环中的 2 个,但它设法绕过了创建 dat2
、dat2b
和 unique_time
。
我的改进答案:
f <- function(i, ii){as.numeric(aggregate(dat[i,ii,], by=list(time),mean)$x)}
for(i in 1:nrow(expand.grid(1:length(lon),1:length(lat)))){
new_dat[expand.grid(1:length(lon),1:length(lat))[i,1],
expand.grid(1:length(lon),1:length(lat))[i,2],] <-
f(expand.grid(1:length(lon),1:length(lat))[i,1],expand.grid(1:length(lon),
1:length(lat))[i,2])
}
减少到只有 1 个循环。我们也可以使用 apply
.