2013-03-25 1 views
0

데이터 세트에서 비 소나기의 길이와 강도 (양)를 추출해야합니다. 데이터는 각 행이 하루 동안의 데이터를 포함하는 행렬입니다. 데이터는 5 분 간격으로 분할되므로 각 열은 5 분 간격 (288 열)입니다. 나는 지금 비 샤워의 시작을 발견하고 멈출 때까지 금액과 길이를 더하고 싶다. 비가 오는 날이 다음날로 확대 될 수 있기 때문에 다음 행을 계속 합산 할 수 있어야합니다. 내 루프가 작동하려면 나는 행렬의 전면에 마지막 열을 추가했지만 (기본적으로 다음의 전면에 이전 행의 마지막 셀을 추가) 한 행 아래로 이동 :셀에서 행 셀을 읽는 방법 (R for for two loops)

# 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) 
    }}}} 

을하지만, 인덱스에서 넘겨받을하지 않는 것 잠시 동안 루프를 for 루프로 돌리면 왜 그걸 찾을 수 없었습니다. while 루프가 다음 라인으로 이동 때, 비가 없다이 라인을 체크 루프 반복에 대해이 출력 참조 : .....

>[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 루프에서 #
[1]"4 ","6 ","동안 "
[1]"4 ","7 ","동안 "
[1]"4 "" 8 "" "동안"
[1] "5" "2" ""# 점프하는 동안 다음 행 정확하게
[1] "5" "3" "동안"
[1] "5", "4", "동안"
[1] "5", "5", "동안"
[1 ] "5" "6" "while"
[1] "5" "3" "else"# if-else 루프에서 # 반복 됨 ...
[1] "5" "4" "else"
[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 ","가상 "
[1]"5 ","8 ","가상 "
[1]"6 ","2 "" "다른 다시 트랙 # ...

[1] "6", "3"

감사 "만약"아래쪽으로 판독! 데이터 세트가 매우 크기 때문에 (여러 스테이션에서 5 분 간격으로 60 년)이 기능을 향상 시키거나 수정하기위한 도움이나 제안이 있으면 높이 평가할 수 있습니다.

+3

이 정보는 '데이터'로 변환하는 것이 좋습니다. 프레임 "두 개의 열. 하나는 데이터이고 다른 하나는 타임 스탬프입니다. 이렇게하면 모든 계산이 극적으로 단순화됩니다. 그 값어치에'매트릭스 '는 차원을 가진'벡터'일 뿐이므로 단일 숫자 인덱스를 사용할 수 있습니다. 즉,'as.vector (t (Dat)) – Justin

+0

코드는 마지막 합계로 147을줍니다. 하지만 당신이 148 (4 + 9 + 14 + 19 + 24 + 1 + 1 + 1 + 5 + 10 + 15 + 20 + 25)를 의미했다고 생각합니다. 아래 답변에서 내 다른 주석을 참조하십시오. –

+0

@ Ferdinand.kraft 답장을 보내 주셔서 감사합니다. 147 올바른지, 마지막 열을 맨 앞줄에 복사하여 행렬의 마지막 셀을 다음 열의 첫 번째 셀로 복사하여 진행중인 또는 새로운 비 이벤트인지 확인하는 것은 서투른 방식입니다. 따라서 첫 번째 열은 셀 수 없다. 그 말이 맞는다면. – KG12

답변

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의 정보를 사용하여 비가 시작되고 멈추는 위치를 결정할 수도 있지만 독자의 연습 문제로 남겨 두겠습니다.

+0

이 코드는'dat.t <- c (t (Dat))':'rain_start <- (dat.t> 0>과 & c (0, dat.t [-length (dat.t))]) == 0)'. 이것은 제로 측정 후에 첫 번째 강우 이벤트를 식별합니다. 그런 다음'aggregate (dat.t, by = list (event = cumsum (rain_start)), FUN = sum) [- 1,]'은 각 이벤트에 대한 비의 양을 제공하고'aggregate (dat.t, by = list FUN = function (x) sum (x> 0)) [- 1,]은 각 청크의 이벤트 수를 나타냅니다. BTW, OP 코드는 마지막 합계에 대해 147을 제공하지만 이것은 버그라고 생각합니다. –

+0

내 코드를 정리하고 줄이는 데는 여러 가지 방법이 있습니다. 그러나 필자의 주요 목표는 읽기 쉽고 명확한 코드를 작성하는 것이 었습니다. 나는'aggregate' 함수의 구문과 가독성이 혼란스럽고 단어로 해석하기 어렵다는 것을 알기 때문에 나는 내 자신의 온전함을 위해 할 수있는 곳에서 여러 줄을 자주 사용한다. – Justin

+0

@Justin 감사합니다. 내 루프보다 훨씬 간단합니다. 나는 적어도 내 비 이벤트의 시작 위치 (day = row)를 요구할 것이고, 그 정보를 얻는 방법에 대해 여전히 숙고하고있다. – KG12