как сократить время выполнения в R-коде с помощью циклов for

#r #for-loop #runtime

#r #for-loop #время выполнения

Вопрос:

целью кода является считывание нескольких дней в определенный сезон и сохранение климатических переменных в массиве. выбор дня основан на другом файле, т.е. дате посева. код работает, но занимает неожиданно много времени. Я должен запустить этот код 156 раз. Заранее приветствуется любая помощь в выполнении этого кода за короткое время, пожалуйста. ниже приведен код с комментариями:

 #Defining an array
prec<-array(0,dim=dim(frac)) # dim(frac) =  377 175  30
#Loop over years 
for (year in c(2:30)) #first year not included because growing season might have started in year 0 (e.g. in winter crop)
{
  print(year 1980) 
# Reading input precipitation files
  inputprec.file<-paste("E:/Paper_2018/Prec/","prec_",1980 year,".nc",sep="")
  inputprec.file.previous<-paste("E:/Paper_2018/Prec/","prec_",1980 year-1,".nc",sep="")

  nc<-nc_open(inputprec.file)
  lons.inp<-ncvar_get(nc,"longitude")
  lats.inp<-ncvar_get(nc,"latitude")
  val<-ncvar_get(nc,"pr")
  nc_close(nc)

# to select exactly the same doamains for the input from files cftfrac and inputprec.file

  xmin<-which(abs(lons.inp-min.lon)<0.01)
  xmax<-which(abs(lons.inp-max.lon)<0.01)
  ymin<-which(abs(lats.inp-min.lat)<0.01)
  ymax<-which(abs(lats.inp-max.lat)<0.01) 

  val<-val[xmin:xmax,ymin:ymax,]

  nc<-nc_open(inputprec.file.previous)
  val.previous<-ncvar_get(nc,"pr")
  nc_close(nc)

  val.previous<-val.previous[xmin:xmax,ymin:ymax,]

# Loopf over length of x and y

  for(x in c(1:377))
    for (y in c(1:175))

    {
      if(!is.na(hdate[x,y,year])) #get rid of excess NAs
        if(hdate[x,y,year]>0) # condition to check if hdate >0
        {
          if(hdate[x,y,year]>sdate[x,y,year]) # if hdat>sdate i.e. kharif season run this part of code otherwise go to else condition
          {
          #condition over 3rd dimention of sdate to slected few days after sowing
            counter=sdate[x,y,year]
            while (counter <= sdate[x,y,year] 29) {
              print(counter)
              counter=counter 1
            }

            prec[x,y,year]<-sum(val[x,y,sdate[x,y,year]:counter])


          }else # if hdat< sdate i.e. rabi season run this part of code 
          {
            #condition over 3rd dimention of sdate to slected few days after sowing 
            counter=sdate[x,y,year-1]
            while (counter <= sdate[x,y,year-1] 59) {
              print(counter)
              counter=counter 1
            }

            prec[x,y,year]<-sum(val.previous[x,y,sdate[x,y,year-]:counter])

           }
        }
    }
} # end of loop over years
  

Комментарии:

1. В общем, циклы for не являются лучшим решением почти для всех проблем в R. Не могли бы вы, пожалуйста, предоставить образец набора данных, например, с помощью dput(head(frac,20)) , чтобы было легче следовать вашему коду.

2. Есть ли какая-либо причина использовать while цикл вместо counter=sdate[x,y,year] 30 и counter=sdate[x,y,year-1] 60 , и вы действительно хотите, чтобы эти цифры были распечатаны (их слишком много, чтобы на них смотреть)?

3. >dput(head(sdate,120)) c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 305L, 305L, 305L, 305L, NA, NA, NA, NA, NA, NA)

4. Я использую счетчик для переменных sdate, но да, конечно, его вывод не требуется.

5. теперь я попробовал код без использования условия while, т.е. счетчик = sdate[x, y, year]; счетчик <- sdate[x, y,year] 29; счетчик = counter 1. это заняло очень короткое время, но полученный результат отличается от предыдущего, который я получил, используя условие while?, любое объяснение / идея, стоящие за этим, пожалуйста