作者andrew43 (讨厌有好心推文後删文者)
看板R_Language
标题Re: [问题] 月平均资料
时间Tue Oct 23 09:32:35 2018
# 已先自
http://0rz.tw/JI056 下载 trmm_2010.nc
library(ncdf4)
library(data.table)
obs <- nc_open("trmm_2010.nc")
lon <- ncvar_get(obs, "lon") # 经度切1440份
lat <- ncvar_get(obs, "lat") # 纬度切400份
time <- ncvar_get(obs, "time") # 单位为小时,共365个
precip <- ncvar_get(obs, "r") # 第一维为lon,第二维为lat,笫三维为time
time2 <-
as.Date(time / 24, format = "%Y-%m-%d", origin = "2010-01-01")
# 先把单位由小时换算成天
##############
# 以每日求12个月平均
# precip.ave.monthly[1, , ] 到 precip.ave.monthly[12, , ] 表示各月均雨量
# 这步很慢,有需要再改写
precip.ave.monthly <-
apply(precip, c(1, 2), function(x) {
tapply(x, month(time2), mean)
})
image(lon, lat, precip.ave.monthly[6, ,]) # 六月份
# 以每日求全年总平均
precip.ave.overall <- apply(precip, c(1, 2), mean)
image(lon, lat, precip.ave.overall)
par(mfrow = c(3, 4),
mar = c(2, 2, 2, 2),
cex = 8 / 12)
for (i in 1:12) {
image(
lon,
lat,
precip.ave.monthly[i, ,],
col = gray(0:255 / 256),
xlab = "",
ylab = ""
)
title(paste("month:", i))
}
※ 引述《AndrewShi (没有你的我)》之铭言:
: [问题类型]:
: 程式谘询(我想用R 做某件事情,但是我不知道要怎麽用R 写出来)
: [软体熟悉度]:
: 入门(写过其他程式,只是对语法不熟悉)
: [问题叙述]:
: 各位大大好,
: 我放入的这笔资料是2010年全球每天的降雨(量)资料,现在我想把每日的降雨量计算成月
: 平均.年平均降雨量,下面我所想到的回圈是可以画得出图来,但画出来感觉不太正确,所以想请
: 教大大们我的回圈是否有问题,能否给我一些提点,谢谢。
: p.s:原本的资料型态中降雨值的维度只包含经度和纬度(2维),所以我用rbind把时间的维
: 度也并到降雨值里。
: [程式范例]:
: rm(list=ls())
: library(ncdf4)
: TRMM_data <- "C:\\Users\\TOM\\Desktop\\R(资料库)\\TRMM资料\\trmm_2010.nc"
: obs <- nc_open(TRMM_data)
: print(obs)
: lon <- ncvar_get(obs, "lon")
: lat <- ncvar_get(obs, "lat")
: time <- ncvar_get(obs, "time")
: precip <- ncvar_get(obs,"r")
: time <- matrix(seq(as.Date("2010-01-01"), as.Date("2010-12-31"),1))
: rbind(dim(time),precip[[3]])
: time <- c()
: for(time in seq_along(1:31)){
: mean(precip)
: }
: time <- c()
: for(time in seq_along(1:365)){
: mean(precip)
: }
: lon <- lon-180
: #lat <- rev(lat)
: precip <- precip[,,time]
: library(RColorBrewer)
: image(lon,lat,precip,col=rev(brewer.pal(10,"RdBu")))
: library(maptools)
: gpclibPermit()
: data(wrld_simpl)
: plot(wrld_simpl,add=TRUE)
: [环境叙述]:
: [关键字]:
: 月平均 nc档 降雨
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 60.248.222.1
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/R_Language/M.1540258357.A.42A.html
1F:推 AndrewShi: 非常感谢andrew大,愿意花这麽多时间帮我解答,我今天 10/23 11:32
2F:→ AndrewShi: 也会好好研究程式码,如果对於你写的程式码有疑惑的话 10/23 11:32
3F:→ AndrewShi: 方便能再请教你吗XD?? 10/23 11:32
4F:推 AndrewShi: abdrew大~我想请教apply里的c(1,2)是指把每列.每行(每 10/23 15:24
5F:→ AndrewShi: 个经度.纬度)的降雨值都带到function里面的意思对吗?! 10/23 15:24
precip 是一个三维阵列,维度按顺序分别是经度、纬度和时间。
apply(precip, c(1, 2), mean) 的意思是,
对 precip 做平均,方式是同经度同纬度而不同时间的值取成一组资料的平均。
这里的 c(1, 2) 就是指第一和第二个维度,即同经度同纬度的意思。
因此,其结果就由365「层」平均成 1 层。
6F:→ AndrewShi: 另外想请问你是怎麽把时间(月)放到precip.ave.monthly 10/23 15:24
7F:→ AndrewShi: 的第一个维度里的呢?? 10/23 15:24
上面如果可以理解,那麽
precip.ave.monthly <-
apply(precip, c(1, 2), function(x) {
tapply(x, month(time2), mean)
})
这句也是类似的。
不过,这次希望同经度同纬度的值在平均时要再按 month(time2) 为组别分别平均。
所以,每个地点会取出 12 个平均,最後结果就是有 12 层。
我这里是利用 month(time2) 将年月日取到月份。
如果你的资料不只一年,那 month(time2) 要改成 substr(time2, 1, 7) 才行,
不然不能区别同月不同年的情况。
※ 编辑: andrew43 (60.248.222.1), 10/23/2018 17:43:50
※ 编辑: andrew43 (60.248.222.1), 10/23/2018 18:31:26
8F:推 AndrewShi: 感谢andrew大详细的解答,上面的叙述我能理解,不过我 10/24 14:47
9F:→ AndrewShi: 很好奇为什麽在单用apply算降雨年平均的时候时间是在 10/24 14:47
10F:→ AndrewShi: 降雨的第三个维度,而在算月平均的时候,时间变成降雨( 10/24 14:47
11F:→ AndrewShi: precip.ave.monthly)的第一个维度,而经.纬度则变成第 10/24 14:47
12F:→ AndrewShi: 二.三个维度,我看不出来哪一段程式码是在做这样的处理 10/24 14:47
13F:→ AndrewShi: 。 10/24 14:47
14F:→ andrew43: 这应该是因为tapply()一次有12个值,所以apply自动把它 10/24 16:59
15F:→ andrew43: 安排在第一个维度。没有哪段码刻意要求达到这种结果。 10/24 17:01
16F:→ andrew43: 再接一个aperm(..., c(2,3,1))转换过来就好了 10/24 17:03
17F:→ andrew43: 另外,单用apply算降雨年平均後只有二维度,并没有时间. 10/24 17:05
18F:推 AndrewShi: 了解,真的非常感谢andrew大,让我学到很多~ 10/24 22:25
19F:推 AndrewShi: andrew大~想再请教你如果想用回圈的概念来写的话,我想 10/25 16:22
20F:→ AndrewShi: 到的写法是:for(i in (1:1440)){ 10/25 16:22
21F:→ AndrewShi: for(j in (1:400)){ 10/25 16:22
22F:→ AndrewShi: mean(precip[i,j,time=(1:31)])}} 10/25 16:22
23F:→ AndrewShi: 但跑出来也只有一个值,所以想请教你我的回圈写法(概 10/25 16:22
24F:→ AndrewShi: 念)是哪里有出错吗?? 10/25 16:22
25F:→ andrew43: 这样是各别算出每个地点一月份的平均雨量,一次算一个。 10/25 16:47
26F:→ andrew43: 那还不如写成apply(precip[,,1:31], c(1,2), mean) 10/25 16:48
27F:→ andrew43: 你若想用for loop一次算一个地点,要把结果填到一个容器 10/25 16:52
28F:→ andrew43: 中,例如一个400*1440矩阵中。 10/25 16:53
29F:推 AndrewShi: 了解,非常感谢~ 10/25 17:09
30F:推 AndrewShi: andrew大~不好意思,想再请教你一个基本问题,把结果 10/26 17:28
31F:→ AndrewShi: 填到一个矩阵里,matrix(mean(precip[i,j,time=(1:31), 10/26 17:28
32F:→ AndrewShi: 1440,400))这样写对吗?? 10/26 17:28
不对。
你似乎不太熟悉一些矩阵或阵列的操作。
请研究以下例子。
a <- array(1:24, c(2, 3, 4))
m <- matrix(NA_real_, nrow = dim(a)[1], ncol = dim(a)[2])
for (i in 1:dim(a)[1]) {
for (j in 1:dim(a)[2]) {
m[i, j] <- mean(a[i, j, ])
}
}
print(a)
print(m)
apply(a, c(1, 2), mean)
※ 编辑: andrew43 (60.248.222.1), 10/26/2018 18:25:27
※ 编辑: andrew43 (60.248.222.1), 10/26/2018 18:27:53
33F:推 AndrewShi: 我懂了,首先先创一个数字由1~24,2列3行共4个(矩阵) 10/27 17:21
34F:→ AndrewShi: 的阵列a,之後再创一个矩阵m,列和行的数目和阵列a的 10/27 17:21
35F:→ AndrewShi: 第一和第二个维度一样(2列3行),最後再把阵列a每个列和 10/27 17:21
36F:→ AndrewShi: 行各别的值(共4个)相加取平均後放到矩阵m里(如:(1+7+13 10/27 17:21
37F:→ AndrewShi: +19)/4=10),我这样的理解应该没有错吧 :)?! 10/27 17:21
38F:推 AndrewShi: 而我的程式应该改为:precip1 <- matrix(precip,1440,40 10/27 17:30
39F:→ AndrewShi: 0) 10/27 17:30
40F:→ AndrewShi: for(i in (1:1440)){ 10/27 17:30
41F:→ AndrewShi: for(j in 1:400)){ 10/27 17:30
42F:→ AndrewShi: precip1[i,j] <- mean(precip[i,j,time=(1:31)])}},非 10/27 17:30
43F:→ AndrewShi: 常谢谢andrew大用引导式的方式教我,其实我也比较喜欢 10/27 17:30
44F:→ AndrewShi: 用这种方式来学习。 10/27 17:30
45F:→ andrew43: 嗯嗯对 10/27 18:28
46F:→ andrew43: 等等。第一句不对啊。 10/27 22:45
47F:→ andrew43: 干嘛把容器的值在计算前就填入旧值。 10/27 22:45
48F:→ andrew43: 我的例子不是这麽写的 10/27 22:47
49F:推 AndrewShi: 抱歉,andrew大,刚刚才看到你最後的回覆,所以我要改 11/02 16:31
50F:→ AndrewShi: 成precip1 <- matrix(precip1,1440,400)这样才对吗?! 11/02 16:31
51F:→ andrew43: 创造一个矩阵,里面先全填成NA或0或某个特定数字都好 11/02 16:56
52F:→ andrew43: 若填成NA,之後你loop完之後,如果还有NA就表示过程有问 11/02 16:58
53F:→ andrew43: 题。你先填入旧资料就不能辨视出哪个值可能有问题了。 11/02 16:59
54F:→ andrew43: 现在你又问是不是先填入precip1,问题是precip1还不存在 11/02 16:59
55F:→ andrew43: 前不可能,就像a未定义时 a <- a+1 怎麽进行? 11/02 17:01
56F:推 AndrewShi: 了解XD,所以我的precip1要改成NA_real_,先把这个建 11/02 18:16
57F:→ AndrewShi: 立出来空的矩阵(precip1)先(随便)填个值(NA或0),之後 11/02 18:16
58F:→ AndrewShi: 再把算出来的平均降雨值填到这个矩阵里。 11/02 18:16
59F:→ andrew43: 我是这样的意思没错 11/02 19:04
60F:推 AndrewShi: andrew大~我想请教你一个问题,如果画图的部分我想画特 11/07 17:19
61F:→ AndrewShi: 定区域的话(如:东亚),改image里的经.纬度范围和月平 11/07 17:19
62F:→ AndrewShi: 均降雨里的经.纬度范围可以画的出来,但是之後再叠加世 11/07 17:19
63F:→ AndrewShi: 界地图(有设成同样范围)的时候画不出来(它有显示有多 11/07 17:20
64F:→ AndrewShi: 少个警告讯息),但我打warnings( ),它也没列出警告讯 11/07 17:20
65F:→ AndrewShi: 息,想请教你这个问题该怎麽解决呢?? 11/07 17:20
66F:→ andrew43: 请不要一直在推文中提出新问题。发文并附code 11/08 10:36
67F:推 AndrewShi: 好的。 11/08 12:01