0

我需要从数据集中提取阵雨的长度和强度(数量)。数据是一个矩阵,其中每一行包含一天的数据。数据以 5 分钟的间隔拆分,因此每列是一个 5 分钟的间隔(288 列)。我现在想找到阵雨的开始,并将雨量和长度相加,直到它停止。因为阵雨可以延续到第二天,所以我需要能够在下一行继续求和。为了使我的循环正常工作,我将最后一列添加到矩阵的前面,但将其向下移动了一行(基本上将上一行的最后一个单元格添加到下一行的前面):

# 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" # 在while循环中
[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”“其他”
[1]“5”“5”“其他”
[1]“5”“6”“其他”
[1]“5”“7”“如果”
[1]“5”“8” "if"
[1] "5" "2" "else" # 在 if-else 循环中重复第 5 行!!!为什么?
[1]“5”“3”“其他”
[1]“5”“4”“其他”
[1]“5”“5”“其他”
[1]“5”“6”“其他”
[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)

还有其他方法,但这是其中之一。如果你愿意,你也可以使用你的信息rle来确定雨开始和停止的位置,但我会把它作为练习留给读者......

于 2013-03-25T17:46:37.500 回答