获取r中每月最长的连续数字,将其相加并存储

时间:2016-03-24 17:07:39

标签: r function matrix storage

我在Stackoverflow的第一个问题:)我希望你能够帮助我。

我试图在数据集中找到每月连续最长的雨天数,将雨总量相加,然后存储下雨持续的天数和矩阵中的雨量之和。我成功地获得了下雨天数并将其存储起来,但是一个场景和283点需要2.5小时才能运行(12个模型x 4个场景要跟随:)。我读到某处读取和写入矩阵是低效的,所以我的猜测是操作可能更有效。

此链接在longest consecutive的路上已经有所帮助,但我的问题更进一步。

对于这个问题,最好使用2年的每日降雨量值,我将其与日期相关联,以找出每个月和每年最长的连续阴雨天数。我将输出写入矩阵。然后在盆地中进行了10分。

用于获取连续数字并将其写入矩阵的函数:

WriteRainyDaysCountToMatrix <- function(myDataFrame, myDates, mymatrix, i)
{
  monthsAmount <- 24
  for (monthNumber in 1:monthsAmount){
  #print(cat("monthNumber = ", monthNumber))
  year <- toString(myDates[monthNumber,2])
  month <- toString(myDates[monthNumber,1])
  dayCounter <- 0
  precipitationMax <- 0
  lastRowPrecipitation <- F

  for (rowNumber in 1:nrow(myDataFrame)){
    rowDate <- myDataFrame[rowNumber,1]
    rowYear <- substr(rowDate,1,4)
    rowMonth <- substr(rowDate,5,6)

    if (rowYear == year && rowMonth == month){
      rowPrecipitation <- myDataFrame[rowNumber,2]

      if (rowPrecipitation > 0){
        dayCounter <- dayCounter + 1
        lastRowPrecipitation <- T
        }
        else{
          if (lastRowPrecipitation == T && precipitationMax == 0){
          precipitationMax <- dayCounter
          dayCounter <- 0
          lastRowPrecipitation <- F
        }
      else if (lastRowPrecipitation == T && precipitationMax < dayCounter){
        precipitationMax <- dayCounter
        dayCounter <- 0
        lastRowPrecipitation <- F
      }
      else{
        dayCounter <- 0
        lastRowPrecipitation <- F
      }
    }
  }
}
if (lastRowPrecipitation == T && precipitationMax == 0){
  precipitationMax <- dayCounter
 }
 mymatrix[[monthNumber,i]] <- precipitationMax
}
return (mymatrix)
}  

此处定义了存储值的空矩阵:

pmatrix_hist <- matrix(data=NA,nrow=12,ncol=10,dimnames=list(c(1:24),c(1:10)))

作为输入的日期(文本文件)myDates:

1981 1981,02 1981,03 1981,04 1981, 05 1981年,06 1981年,1981年1981年,1981年,1981年,1981年,1981年, 11 1981年,12 1981年,01 1982年,02年1982年,03年1982年,04年,1982年, 05 1982年,06 1982年,1982年,1982年,1982年,1982年,1982年,1982年, 1982年12月,1982年12月等

Time_step_hist来自包含以这种格式超过2年的日期的文本文件:

19810101,19810102,19810103,19810104,19810105等

然后一个for循环为我做的工作:

for (i in 1:10) {
   # loop over dates and acquire date       
   Prec_hist = read.table(paste(P_read_table_hist$V1[i]), header=F)
   # then put date and rain together
   data_Prec_Hist <- data.frame(Time_step_hist[1:7305,],     Prec_hist[1:7305,]) 
   # call function to get and write to matrix
   pmatrix_hist <- WriteRainyDaysCountToMatrix(data_Prec_Hist,  Dates_hist, pmatrix_hist, i)
   }

我不知道如何输入我使用过的雨数据,但可以使用0和1的简单列表。

在矩阵中只存储了天数,第二个矩阵用于存储连续几天的降雨量。

最大的性能提升在哪里?

非常感谢提前!

1 个答案:

答案 0 :(得分:0)

欢迎! 你的直觉是正确的,这种操作应该在几秒钟而不是几小时内测量。

你最大的收获来自最小化循环和使用矢量化函数。

一个好的起点是使用as.Date将字符串转换为日期,并使用子集来简化循环。

请考虑as.Date('19810101',"%Y%m%d")将字符串转换为日期,而不是所有那些嵌套循环经过多年和几个月。

以下是修改过的结构可能看起来的样子,我不得不猜测你的“myDataFrame”有一列日期和一列降水值。

set.seed(42)#for repeatability
#Dummy Data
#some dates
dates <- seq(as.Date("19810101","%Y%m%d"), as.Date("19821231","%Y%m%d"), by = "day")
#random Precipitation
precip <- sample(0:3,length(dates), replace = TRUE, prob = c(.7,.1,.1,.1))
myDataFrame<- data.frame(dates,precip)

#
#real code
#

#Create a month Column
myDataFrame$month <- as.numeric(format(myDataFrame$dates,'%m'))
myDataFrame$year <- as.numeric(format(myDataFrame$dates,'%Y'))

#order your data frame by date
myDataFrame[order(as.Date(myDataFrame$dates)),]

#create lists of the months, and years to drive loops later
yr_list <- levels(factor(myDataFrame$year))
mo_list <- levels(factor(myDataFrame$month))

#A smoother loop structure will look like like this, relying on subsetting 
for(y in yr_list){
  suby <- subset(myDataFrame, myDataFrame[,"year"] == y)
  for(m in mo_list){
    subm <- subset(suby, suby[,"month"] ==m)
    for(d in 1:length(subm)){
      #here you can run your count for each month, and then write the record
      #to a data structure of your choosing
        } 
      }
    }

将来会有所帮助的一些事情:1)输出你的数据源的样子2)显示你想要输出的最小例子。

一些提示一般提示:将您引入脚本的日期子集可以帮助您更快地进行迭代,并查找system.time()和proc.time()以测量您的代码,以查看您所做的改进。 / p>