sst数据矩阵序列的循环或函数

时间:2012-07-25 11:44:24

标签: r

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

来自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)并应用两个自定义函数的表面积 lat strip 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或表面区域一个纬度(纬度)条带SA的表面和SAM月份所有条带的面积,温度上限(tmu)。

来自函数SA的矩阵具有sst的表面积> 1。 tmu(比如说12°C)表示纬度(纬度)(比如30°N)和功能SAM的矩阵(sa)有所有纬度的总和(从30°N到70°N)。这样做的工作是一个月,我可以重复这些功能12次,以16年的方式获得这一年或172次:

我定义一个起始纬度(纬度),然后是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。提前谢谢。

1 个答案:

答案 0 :(得分:2)

如果我理解了您的问题,那么您的代码就会缩小到

#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输入和输出数据集。