Skip to content

Loop problem

4 messages · Jamie Ledingham, jim holtman, Jim Lemon

#
Dear all, I have a problem with a loop, if anyone has any knowledge on
these things I would appreciate some comments.  The code below is
designed to allow me to extract the top record of the data frame, and
them remove rows from the data frame which have an index close to the
extracted top record.


topstorm<-subset(rankeddataset[1,]) ## Extracts the top storm
topstormindex<-rankeddataset[1,1] ## Finds the top storm start index
startindex<-topstormindex-48 ## sets the start and end indexes
endindex<-topstorminde+48
rankeddataset<-rankeddataset[-1,] ## Creates a new list with the top
storm removed

##This section of code needs looped.  It removes storms from the list
which are too close to the extracted storm

for (i in 1:30){
if (rankeddataset[i,1]>startindex && rankeddataset[i,1]<endindex)
{rankeddataset<-rankeddataset[-i,]}
}

Here is some example data:

   82856  15 / 6 / 1966   82856:82879            25.9
   82857  15 / 6 / 1966   82857:82880            20.5
   83036  23 / 6 / 1966   83036:83059            17.3
   87250 15 / 12 / 1966   87250:87273            15.9

The loop does not currently work, it seems to remove every second line
or so.  Can anyone suggest why this might be, I'm not particularly
experienced in using loops so it may be a rookie mistake.  Thanks in
advance.
Jamie Ledingham
#
Basically you are moving the data up and then incrementing to the next
row.  Here is an example; assume that you are at the 2nd entry:

1
2 <== here
3
4

Now your loop index is 2 and you remove the current data ('2') and are
left with:

1
3  <==  index of 2 points here
4

Now you increment the index to 3 and you get

1
3
4 <== now here

So you have skipped 3.  What you should be doing is determining all
the index values that meet your criteria and then deleting them all at
once, or start from the bottom of the dataframe and work up.
On 3/26/08, Jamie Ledingham <jamie.ledingham at newcastle.ac.uk> wrote:

  
    
#
Jamie Ledingham wrote:
Hi again Jamie,
I had a bit of time tonight and recognized your problem. I think the 
following function will do what you want, although it is probably not 
the most elegant solution. I would check it manually with a small data 
file and a small "howmany" argument to make sure that it is picking up 
the maxima you want.

find.max.rain<-function(raindata,howmany) {
  # a lazy way of getting the same structure as raindata
  # it assumes that raindata has the data structure that you want
  maxrain<-raindata[1:howmany,]
  for(i in 1:howmany) {
   # get the current number of rows
   nrows<-dim(raindata)[1]
   # find the first maximum value
   thismax<-which.max(raindata$cumrain)
   # transfer it to the return data frame
   maxrain[i,]<-raindata[thismax,]
   # calculate the minimum index for the 48 hour gap
   mindex<-thismax-48
   # make sure it is at least 1
   if(mindex < 1) mindex <- 1
   # calculate the maximum index for the gap
   maxdex<-thismax+48
   # make sure it doesn't go past the end of the data frame
   if(maxdex > nrows) maxdex<-nrows
   # chop out that time period
   raindata<-raindata[-(mindex:maxdex),]
  }
  return(maxrain)
}

Jim
#
Oops, missed the first line of the example:

storm.data<-data.frame(meas.index=10001:20000,cumrain=runif(10000,-10,10)+10)

You can generalize the function to whatever column names you have like this:

find.max.rain<-function(raindata,howmany,raincol) {
  # a lazy way of getting the same structure as raindata
  # it assumes that raindata has the data structure that you want
  maxrain<-raindata[1:howmany,]
  for(i in 1:howmany) {
   raindim<-dim(raindata)
   thismax<-which.max(raindata[[raincol]])
   cat(thismax," ")
   maxrain[i,]<-raindata[thismax,]
   mindex<-thismax-48
   if(mindex < 1) mindex <- 1
   maxdex<-thismax+48
   cat(mindex,maxdex," ")
   if(maxdex > raindim[1]) maxdex<-raindim[1]
   raindata<-raindata[-(mindex:maxdex),]
   cat(raindim[1],"  ")
  }
  cat("\n")
  return(maxrain)
}

find.max.rain(storm.data,50,"cumrain")

Jim