【问题标题】:Loop or function for sequence of matrices of sst datasst数据矩阵序列的循环或函数
【发布时间】:2012-07-25 11:44:23
【问题描述】:

我一直在寻找一种方法,以按月从一系列海面温度 (sst) 矩阵中选择 R 范围内值的频率。这些数据排列为 (sst, 80*40*172),即北大西洋的 (sst, longitude,latitude, month)。我对这些频率很感兴趣,因为我用它们来计算每个月在 sst 范围内的表面积,比如在 4°C 到 12°C 等温线之间。我经常使用 R 对时间序列和空间数据进行统计分析,但我不习惯编程,所以我的方法可能不是最有效的。我已经成功提取了一个月内所有纬度的 sst 值 >12°C 的频率:

我来自 IRI/LDEO 气候研究网站的数据

dat <- read.table("c:/Temp/[Y+X]datatable.tsv", header=FALSE, sep="\t")

第一个月的 5x5 样本矩阵

    Nov 1981    30.5000 31.5000 32.5000 33.5000
    9.50000     21.7906 21.9431 22.1324 22.1662
    8.50000     21.7267 21.8573 21.9981 21.8757
    7.50000     21.6644 21.7781 21.8960 21.7393
    6.50000     21.5989 21.7025 21.8044 21.6304

我基本上跳过了经度,行标签我也打算在后面添加日期。首先,我将第一个月提取为矩阵 (t) 并应用两个自定义函数表面积 纬度带 SA 和 MSA 月份所有纬度带的表面积。

ro=2:81
co=2:41
t <- as.matrix(dat[ro,co])

然后

SA <- function (lat,tmu){
    l <- c(t[,lat]>=tmu,0)
    la <- as.data.frame(l)
    x  <- la[,1] 
    n  <- length(x)
    sau <- array(0,n)
    x. <- lat
    for (i in 1:n) sau[i] <- (x[i]*111.320)*(cos(x.*(3.1415/180))*111.320)
    s <- as.matrix(sum(sau))
}
MSA <- function(tmu){
    m <-1:40
    su <- array(0,0)
    for (i in 1:40) su[i] <-SA(m[i],tmu)
    ms <- as.data.frame(su)
    sa <- as.data.frame(colSums (ms))
    return(sa)
}

函数 SA 和 MSA 或表面积一个纬度 (lat) 带 SA 的表面和月份 SAM 的所有带的面积,用于温度上限 (tmu)。

来自函数 SA 的矩阵 (s) 的表面积为 sst> tmu(比如 12 °C) 用于纬度 (lat)(比如 30°N),来自函数 SAM 的矩阵 (sa) 具有所有纬度(从 30°N 到 70°N)。这可以完成一个月的工作,我可以重复这些函数 12 次以获得年份或 16 年的 172 次:

我定义了一个起始纬度 (lat),然后是 81 个经度单元 (st) 的步骤,以提取下一步和所需的温度;

lat= 30.5 
st=81 
t=12

然后计算每个月的总表面积;

SA1 <- {
    i=0*st 
    t <- as.matrix(dat[ro+i,co])
    SA(lat,t)
    MSA(12)
}

SA2 <- {
    i=1*st 
    t <- as.matrix(dat[ro+i,co])
    SA(30.5,t)
    MSA(12)
}

我的问题是,是否有可能创建一个循环或函数来遍历所有月份,即 172 次,因此跳过重复 SA1、SA2...SA172。提前致谢。

【问题讨论】:

  • 你能指定你使用哪个数据集吗?
  • 您的数据集中的月/年是如何组织的?您可以将它们全部放入一个数组中,例如:fullData=array(0,dim=c(80,40,12,16) 然后填充它吗?
  • 抱歉 Alan (stackoverflow.com/users/1529381/alan),我没有注意到您的评论。这些数据是来自 Reyn_SmithOIv2 数据集的海面温度 (SST)。
  • 你好(stackoverflow.com/users/1474724/discretecircle)。 IRI/LDEO wweb 页面中的实用程序(iridl.ldeo.columbia.edu/)delivers 各种格式的数据(ncdf、hdf 或作为 DOD 链接到气候数据中的 FERRET 或 GRads 或 Matlab 工具箱)。我选择将其作为月值数组获取,如图所示上面,这个请求从 1981 年 11 月开始,以 lats. 作为列和 longs. 作为行,并且有 172 个步骤,即 12 年的数据。我会按照你的建议将它们放入一个数组中。

标签: r


【解决方案1】:

如果我理解您的问题,您的代码会简化为这样

#create some dummy data
lat <- 30:33
lon <- 6:9
sst <- array(rnorm(length(lat) * length(lon) * 12, mean = 21, sd = 4), 
    dim = c(length(lat), length(lon), 12), dimnames = list(lat, lon, 1:12))
#the actual code
SA <- function (test, tmu){
  colSums(test >= tmu) * 111.320 ^ 2 * 
     cos(as.numeric(rownames(test)) * (pi/180))
}
apply(sst, 3, SA, tmu = 21)

如果这不正确,请让您的问题更清楚,并提供reproducible 输入和输出数据集。

【讨论】:

  • 非常感谢蒂埃里,我会看看它对我有用,否则我会按照你的建议做。
  • 再次感谢蒂埃里,看来这完全取决于了解 R 处理行和列的方式。你的代码很简洁,完全符合我的需要,只是你翻了很长时间,但这很容易修复。
猜你喜欢
  • 1970-01-01
  • 2021-03-22
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
相关资源
最近更新 更多