R - Error in For Loops and If Statements on list of Data Frames: Subscript Out of Bounds -
i'm using r create occupancy model encounter history. need take list of bird counts individual leks, separate them year, code count dates 2 intervals, either within 10 days of first count (interval 1), or after 10 days after first count (interval 2). year 1 count occurred need add entry coded "u", indicate no count occurred during second interval. following need subset out max count in each year , interval. sample dataset:
complexid date males year category 57 1941-04-15 97 1941 57 1942-04-15 67 1942 57 1943-04-15 44 1943 57 1944-04-15 32 1944 57 1946-04-15 21 1946 57 1947-04-15 45 1947 57 1948-04-15 67 1948 57 1989-03-21 25 1989 57 1989-03-30 41 1989 57 1989-04-13 2 1989 57 1991-03-06 35 1991 57 1991-04-04 43 1991 57 1991-04-11 37 1991 57 1991-04-22 25 1991 57 1993-03-23 6 1993 57 1994-03-06 17 1994 57 1994-03-11 10 1994 57 1994-04-06 36 1994 57 1994-04-15 29 1994 57 1994-04-21 27 1994
now here code wrote accomplish task, naming dataframe above "c1" (you'll need coerce date column date, , category column character):
c1_year<-lapply(unique(c1$year), function(x) c1[c1$year == x,]) #splits complex counts list year for(i in 1:length(c1_year)){ c1_year[[i]]<-cbind(c1_year[[i]], daydiff = as.numeric(c1_year[[i]][,2]-c1_year[[i]][1,2])) } #adds column difference between first survey , subsequent surveys for(i in 1:length(c1_year)){ c1_year[[i]]<-if(length(c1_year[[i]][,1]) == 1) rbind(c1_year[[i]], c(c1_year[[i]][1,1], na, 0, c1_year[[i]][1,4], "u", 11)) } # adds u values years 1 count, while coercing "u" appropriate interval for(i in 1:length(c1_year)){ c1_year[[i]]$interval<- ifelse(c1_year[[i]][,6] < 10, 1, 2) } # adds interval code each survey, 1 = less ten days after first count, 2 = more 2 days after count for(i in 1:length(c1_year)){ c1_year[[i]]<-ddply(.data=c1_year[[i]], .(interval), subset, males==max(males)) } # subsets out max count in each interval
the problem arises during second for-loop, when options(error=recover)
enable returns: error in c1_year[[i]] : subscript out of bounds no suitable frames recover()
` @ point code accomplishes supposed , adds line each year 1 count, though error message generated rows "u" code still appended data frames. issue have 750 leks for. tried build code above function, when run function on data subscript out of bounds error stops function running. brute force , run code above each lek manually, hoping there might more elegant solution. need know why getting subscript out of bounds error, , how can fix it?
here's function wrote, can see doesn't work:
create.oeh<-function(dataset, final_dataframe){ c1_year<-lapply(unique(dataset$year), function(x) dataset[dataset$year == x,]) #splits complex counts list year for(i in 1:length(c1_year)){ c1_year[[i]]<-cbind(c1_year[[i]], daydiff = as.numeric(c1_year[[i]][,2]-c1_year[[i]][1,2])) } #adds column difference between first survey , subsequent surveys for(i in 1:length(c1_year)){ c1_year[[i]]<-if(length(c1_year[[i]][,1]) == 1) rbind(c1_year[[i]], c(c1_year[[i]][1,1], na, 0, c1_year[[i]][1,4], "u", 11)) } # adds u values years 1 count, for(i in 1:length(c1_year)){ c1_year[[i]]$interval<- ifelse(c1_year[[i]][,6] < 10, 1, 2) } # adds interval code each survey, 1 = less ten days after first count, 2 = more 2 days after count for(i in 1:length(c1_year)){ c1_year[[i]]<-ddply(.data=c1_year[[i]], .(interval), subset, males==max(males)) } #subset out max count each interval df<-rbind.fill(c1_year) #collapse list single dataframe final_dataframe<-df[!duplicated(df[,c("year", "interval")]),] #remove ties max count }
in bit of code
for(i in 1:length(c1_year)){ c1_year[[i]]<-if(length(c1_year[[i]][,1]) == 1) rbind(c1_year[[i]], c(c1_year[[i]][1,1], na, 0, c1_year[[i]][1,4], "u", 11)) }
you assigning null if length(c1_year[[i]][,1]==1
not true, removes elements c1_year
entirely.
you want
for(i in 1:length(c1_year)){ if (length(c1_year[[i]][,1]) == 1) { c1_year[[i]] <- rbind(c1_year[[i]], c(c1_year[[i]][1,1], na, 0, c1_year[[i]][1,4], "u", 11)) } }
however, see using ddply
, may able avoid lot of replication. ddply(c1, .(year), ...)
splits c1
unique years.
c2 <- ddply(c1, .(year), function (x) { # create 'interval' x$interval <- ifelse(x$date - x$date[1] < 10, 1, 2) # extract max males per interval o <- ddply(x, .(interval), subset, males==max(males)) # add 'u' col if no '2' interval if (all(o$interval != 2)) { o <- rbind(o, list(o$complexid, na, 0, o$year, 'u', 2)) } # return resulting dataframe o })
i converted rbind(.., c(...))
rbind(.., list(...))
avoid converting string (which c
because cannot handle multiple different types).
otherwise code same yours.
Comments
Post a Comment