-1

I've a function that takes as an input two dates, and returns the number of seasons between them.

nSeason<-function(date1,date2){
  n=0
  date1<-as.Date(date1, "%Y-%m-%d")
  date2<-as.Date(date2,"%Y-%m-%d")
  d<-date1:date2
  for(i in d){
    if(!(getSeason(as.Date(i,origin="1970-01-01")) == getSeason(as.Date(i,origin="1970-    01-01")+1))){
      n=n+1
    }
  }
  return(n)
}

getSeason <- function(DATES) {
  repr <- as.Date("2012-03-21", format = "%Y-%m-%d") 
  pos_repr <- as.Date("2012-7-1",  format = "%Y-%m-%d") 
  inverno<- as.Date("2012-10-21",  format = "%Y-%m-%d") 

  # Convert dates from any year to 2012 dates
  d <- as.Date(strftime(DATES, format="2012-%m-%d"))

  ifelse (d >= repr & d < pos_repr, "repr",
          ifelse (d >= pos_repr & d < inverno, "pos_repr","inverno"))
}

This function works just fine, but when I try to apply it to a data.frame with two columns (capture_date, end_date), I get an error:

for(i in 1:length(dados$ano_captura)){
  dados$freq[i]<-nSeason(dados$capture_date[i], dados$end_date[i])
  dados$freq[i]<-dados$freq[i]+1
  if(dados$status[i]==0){
    dados$freq[i]=1
  }
}


Error in date1:date2 : argument of length 0

What seems to be the problem? I can't find it..

Edit (data from OP's comment):

str(dados) 'data.frame':    154 obs. of 42 variables: 
$ id : int 1 2 3 4 5 6 7 8 9 10 ... 
$ Ref_ind : Factor w/ 118 levels "","150,035","150,045",..: 5 7 11 14 21 22 28 8 16 10 ... 
$ capture_date : Date, format: "2009-04-06" "2009-04-06" ... 
$ status : int 1 1 1 1 1 1 1 1 1 1 ... 
$ X : int NA NA NA NA NA NA NA NA NA NA ... 
$ end_date : Date, format: "2009-11-03" "2010-11-28" ... 

Here's the first line of d:
[1] 14340 14341 14342 14343 14344 14345 14346

And here's the reproducible example:

dados<-matrix(c("2009-04-06" ,"2009-04-06" ,"2009-04-07","2009-04-07",
            "2009-04-07", "2009-04-08","2009-11-03", "2010-11-28", "2009-08-30",
        "2009-11-22", "2010-01-28", "2009-05-07"),ncol=2,nrow=6)
colnames(dados)<-c("capture_date","end_date")
dados<-data.frame(dados)
dados$capture_date<-as.Date(dados$capture_date,"%Y-%m-%d")
dados$end_date<-as.Date(dados$end_date,"%Y-%m-%d")
dados$status<-c(1,1,1,1,1,1)
JMarcelino
  • 904
  • 4
  • 13
  • 30
  • Stick a `browser()` line right before `d<-date1:date2` to see what those objects look like. Or use `debugonce(nSeason)`. – Blue Magister Nov 25 '13 at 15:14
  • I would expect that one or both of the date variables do not exist as typed in `dados`, therefore `NULL` is being passed to `:` – James Nov 25 '13 at 15:23
  • I thought of that too, but it's not the case... When I try to do it manually, it works fine – JMarcelino Nov 25 '13 at 15:27
  • Can you post the results of `str(dados)`? – James Nov 25 '13 at 15:37
  • str(dados) 'data.frame': 154 obs. of 42 variables: $ id : int 1 2 3 4 5 6 7 8 9 10 ... $ Ref_ind : Factor w/ 118 levels "","150,035","150,045",..: 5 7 11 14 21 22 28 8 16 10 ... $ capture_date : Date, format: "2009-04-06" "2009-04-06" ... $ status : int 1 1 1 1 1 1 1 1 1 1 ... $ X : int NA NA NA NA NA NA NA NA NA NA ... $ data_fim : Date, format: "2009-11-03" "2010-11-28" ... – JMarcelino Nov 25 '13 at 15:40
  • Meanwhile I've modified the date format from "%d-%m-%Y" to "%Y-%m-%d". – JMarcelino Nov 25 '13 at 15:44
  • 1
    The answer is not obvious to me, and I can't run your code. Unless you can provide a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) I can't help here. – Blue Magister Nov 25 '13 at 16:19
  • Dumb question - but what do the contents of `d` look like? If they're not numeric probably can't generate an (integer) sequence. – Carl Witthoft Nov 25 '13 at 17:22
  • 1
    There is no `dados$ano_captura` ? So `length(dados$ano_captura)` returns `[1] 0`. This is the reason the pros use `seq_along` rather than `1:length()`. – IRTFM Nov 30 '13 at 20:03

2 Answers2

1

Ok, I solved the problem by replacing length(dados$ano_captura). It was miswritten...

for(i in 1:lenght(dados$status){
  dados$freq[i]<-nSeason(dados$capture_date[i], dados$end_date[i])
  dados$freq[i]<-dados$freq[i]+1
  if(dados$status[i]==0){
    dados$freq[i]=1
  }
}

Thank you all

JMarcelino
  • 904
  • 4
  • 13
  • 30
0

OK the reproducible example maybe needs a bit of work???

    dados<-matrix(c("2009-04-06" ,"2009-04-06" ,"2009-04-07","2009-04-07",
                    "2009-04-07", "2009-04-08","2009-11-03", "2010-11-28", "2009-08-30",
                "2009-11-22", "2010-01-28", "2009-05-07"),ncol=2,nrow=6)
    colnames(dados)<-c("capture_date","end_date")
    # at this point dados is a matrix not a data.frame

    # now it's a vector of dates    
    dados<-as.Date(dados,"%Y-%m-%d")

either way it cannot be called like

nSeason(dados$capture_date[i], dados$end_date[i])

I'm not sure if that or similar is the problem with your actual data too???

Stephen Henderson
  • 6,340
  • 3
  • 27
  • 33