0

データセットからにわか雨の長さと強さ(量)を抽出する必要があります。データは、各行に1日のデータが含まれるマトリックスです。データは5分間隔で分割されるため、各列は1つの5分間隔(288列)になります。レインシャワーの始まりを見つけて、止まるまでの量と長さを合計したいと思います。にわか雨は翌日まで続く可能性があるので、次の列で合計を続けることができる必要があります。ループを機能させるために、最後の列をマトリックスの前に追加しましたが、1行下に移動しました(基本的に、前の行の最後のセルを次の行の前に追加します)。

# create an example matrix
Dat=matrix(1:25, 5, 5)
a=c(0,0,0,0,1) # last column added to the front
b=c(0,0,0,1,0) # last column
Dat=cbind(a,Dat,b,b)
e=c(0,0,0,0,0,0,0,0) # just another row
Dat=rbind(Dat,e)

マトリックスは次のようになります

0 1  6 11 16 21 0 0   
0 2  7 12 17 22 0 0  
0 3  8 13 18 23 0 0  
0 4  9 14 19 24 1 1  
1 5 10 15 20 25 0 0  
0 0  0  0  0  0 0 0

今、私は自分のコードを実行します:

Rain=0
Length=0
results=data.frame()
i=1
j=2

for (i in 1:nrow(Dat)) { # rows
for (j in 2:ncol(Dat)) {  # cols

  if(Dat[i,j]==0){   # if there is no rain 
    print(c(i,j,"if"))
    j=j+1            # move on to next cell
       if(j==(ncol(Dat)+1)){ # at the end of the line,move to the next row
      i=i+1
      j=2 
    }} 
  else {print(c(i,j,"else")) # if there is rain

    if (Dat[i,j-1]==0) { # check if there was no rain before => start of rain)
     Rain=0 
     Length=0 
     while(Dat[i,j]>0){  # while it is raining, add up
        print(c(i,j,"while"))
        Rain=Rain+Dat[i,j]
        Length=Length+5
        j=j+1        # move to next cell
        if(j==(ncol(Dat)+1)){ # at the end of a row, move to the beginning of the next
         i=i+1
         j=2
         }
      }
      results_vector=c(Rain,Length) # save the results
      results=rbind(results, results_vector)
    }}}}

これは非常にうまく機能します(つまり、合計された結果は問題ありません)が、インデックスはwhileループからforループに渡されないようで、理由がわかりませんでした。したがって、whileループが次の行にジャンプすると、forループは、雨が降っていないこの行のチェックを繰り返します。出力を参照してください。

>[1] "1"    "2"    "else"   
>[1] "1"     "2"     "while"   ** #enters while loop**  
>[1] "1"     "3"     "while"     
>[1] "1"     "4"     "while"   
>[1] "1"     "5"     "while"   
>[1] "1"     "6"     "while"   
>[1] "1"    "3"    "else"     **#exit while loop, but runs in if-else loop**   
>[1] "1"    "4"    "else"    
>[1] "1"    "5"    "else"   
>[1] "1"    "6"    "else"   
>[1] "1"  "7"  "if"  
>[1] "1"  "8"  "if"  
>[1] "2"    "2"    "else"      **# next line**  
>[1] "2"     "2"     "while"  
>[1] "2"     "3"     "while"

....。

[1] "4" "5" "while" #inwhileループ
[1]"4" "6" "while"
[1] "4" "7" "while"
[1] "4" "8" " while "
[1]" 5 "" 2 "" while " #次の行に正しくジャンプし
ます[1]" 5 "" 3 "" while "
[1]" 5 "" 4 "" while "
[1]" 5 " "5" "while"
[1] "5" "6" "while"
[1] "5" "3" "else" #if-elseループで繰り返されます...
[1] "5" "4 "" else "
[1]" 5 "" 5 "" else "
[1]" 5 "" 6 "" else "
[1]" 5 "" 7 "" if "
[1]" 5 "" 8 " "if"
[1] "5" "2" "else" #if-elseループで行5を繰り返します!!!なぜですか?
[1] "5" "3" "else"
[1] "5" "4" "else"
[1] "5" "5" "else"
[1] "5" "6" "else"
[1 ] "5" "7" "if"
[1] "5" "8" "if"
[1] "6" "2" "if" #トラックに戻る...
[1] "6" "3" "もしも"

一番下まで読んでくれてありがとう!データセットが非常に大きいため(複数のステーションで5分間隔で60年)、これを改善/修正するためのヘルプや提案をいただければ幸いです。

4

1 に答える 1

0

雨が降った日時が気になる場合は、コメントでのアドバイスに従いますdata.frame。そうでない場合、以下は、大規模なデータで高速であるはずのベクトル化されたソリューションです。

日数を気にしない場合は、最初にデータを単一のベクトルに変換します。

dat.t <- c(t(Dat))

これで、ブールチェックを使用してシーケンスを取得できます。

rain_events <- dat.t != 0

を使用しrleて、各イベントの期間を取得できます。

rain_rled <- rle(rain_events)
# I'm using the fact that my values are logical.
# this is equivalent to rain_rled$values == TRUE.
rain_duration <- rain_rled$lengths[rain_rled$values]  

次に、量を決定する必要があります。

total_rain <- cumsum(dat.t)
total_rain_shift <- c(total_rain[-1], 0)

sums <- unique(total_rain[total_rain == total_rain_shift])
rain_fall <- c(sums[1], sums[2:length(sums)] - sums[1:(length(sums)-1)])

out <- data.frame(rain_duration = rain_duration,
                  rain_fall = rain_fall)

他の方法もありますが、これは1つです。必要に応じて、あなたの情報を使用しrleて雨が降り始めた位置と止まった位置を特定することもできますが、それは読者の練習問題として残しておきます...

于 2013-03-25T17:46:37.500 に答える