2012-07-25 82 views
1

我一直在尋找一種方法來從一系列海面溫度(sst)矩陣的月份中選擇R範圍內的值的頻率。這些數據排列爲(sst,80 * 40 * 172),即北大西洋的(sst,經度,緯度,月份)。我對這些頻率很感興趣,因爲我用它們來計算每個月在sst範圍內的表面積,例如4℃和12℃等溫線之間。我經常使用R來進行時間序列和空間數據的統計分析,但是我不習慣編程,所以我的方法可能不是最有效的。我已經成功地對說的SST值提取頻率> 12℃,在1個月所有緯度: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),並應用兩個自定義函數表面積 拉帶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的矩陣對於緯度(lat)(例如在30°N)具有sst> tmu(比如說12°C)的表面積並且來自函數SAM的Matrix(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迭代函數。提前致謝。

+0

你能指定你使用哪個數據集嗎? – Alan 2012-07-25 12:24:19

+0

您的數據集中月/年是如何組織的?你可以把它們全部放入一個數組中,例如:'fullData = array(0,dim = c(80,40,12,16)',然後填充它嗎? – DiscreteCircle 2012-07-25 13:32:54

+0

對不起Alan(stackoverflow.com/users/1529381/alan),這些數據是來自Reyn_SmithOIv2數據集的海面溫度(SST)。 – JHF03 2012-07-26 10:44:20

回答

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輸入和輸出數據集。

+0

Thaks非常Thierry,我會看到它是如何工作的,否則我會按你的建議去做。 – JHF03 2012-07-25 16:03:51

+0

再次感謝Thierry,它似乎是知道R處理行和列的方式。你的代碼是完整的,完全符合我的需求,只是你翻了一翻,但很容易修復。 – JHF03 2012-07-26 00:09:05