簡體   English   中英

R-數據循環列表中的For循環和If語句中的錯誤:下標超出范圍

[英]R - Error in For Loops and If Statements on list of Data Frames: Subscript Out of Bounds

我正在使用R創建一個居住模型遭遇歷史記錄。 我需要列出單個韭菜的鳥類計數清單,按年份將它們分開,然后將計數日期編碼為兩個間隔,或者是在第一次計數的10天內(間隔1),或者是在第一次計數之后的10天之后(間隔) 2)。 對於僅發生1個計數的任何年份,我都需要添加一個編碼為“ U”的條目,以指示在第二個間隔期間沒有計數。 之后,我只需要細分每年和間隔中的最大計數。 樣本數據集:

 ComplexId       Date Males Year category
        57 1941-04-15    97 1941        A
        57 1942-04-15    67 1942        A
        57 1943-04-15    44 1943        A
        57 1944-04-15    32 1944        A
        57 1946-04-15    21 1946        A
        57 1947-04-15    45 1947        A
        57 1948-04-15    67 1948        A
        57 1989-03-21    25 1989        A
        57 1989-03-30    41 1989        A
        57 1989-04-13     2 1989        A
        57 1991-03-06    35 1991        A
        57 1991-04-04    43 1991        A
        57 1991-04-11    37 1991        A
        57 1991-04-22    25 1991        A
        57 1993-03-23     6 1993        A
        57 1994-03-06    17 1994        A
        57 1994-03-11    10 1994        A
        57 1994-04-06    36 1994        A
        57 1994-04-15    29 1994        A
        57 1994-04-21    27 1994        A

現在,這里是我為完成任務而編寫的代碼,將數據框命名為“ c1”上方(您需要將日期列強制轉換為日期,將類別列強制轉換為字符):

c1_Year<-lapply(unique(c1$Year), function(x) c1[c1$Year == x,]) #splits complex counts into list by 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 with difference between first survey and 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 to years with only 1 count,  while coercing the "u" into the appropriate interval

for(i in 1:length(c1_Year)){
  c1_Year[[i]]$Interval<- ifelse(c1_Year[[i]][,6] < 10, 1, 2)
} # adds interval code for each survey, 1 = less than ten days after first count, 2 = more than 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

問題出現在第二個for循環中,當啟用options(error=recover)返回: Error in c1_Year[[i]] : subscript out of bounds No suitable frames for recover() `此時,代碼完成了什么工作它應該並且每年僅用一個計數就增加一條額外的行,即使生成了錯誤消息,帶有“ U”代碼的額外行仍會附加到數據幀中。 問題是我有750韭蔥可以做到這一點。 因此,我嘗試將上面的代碼構建為一個函數,但是,當我對任何數據運行該函數時,下標超出范圍錯誤會阻止該函數運行。 我可以蠻力地執行它,只為每個瀝水手動運行上面的代碼,但是我希望可能會有一個更優雅的解決方案。 我需要知道的是為什么我會出現下標超出范圍的錯誤,並且該如何解決?

這是我編寫的函數,因此您可以看到它不起作用:

create.OEH<-function(dataset, final_dataframe){
  c1_Year<-lapply(unique(dataset$Year), function(x) dataset[dataset$Year == x,]) #splits complex counts into list by 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 with difference between first survey and 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 to years with only 1 count,

  for(i in 1:length(c1_Year)){
    c1_Year[[i]]$Interval<- ifelse(c1_Year[[i]][,6] < 10, 1, 2)
  } # adds interval code for each survey, 1 = less than ten days after first count, 2 = more than 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 for each interval

  df<-rbind.fill(c1_Year) #collapse list into single dataframe

  final_dataframe<-df[!duplicated(df[,c("Year", "Interval")]),] #remove ties for max count

}

在這段代碼中

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)) 
  } 

如果length(c1_Year[[i]][,1]==1不正確,則您將分配NULL,這將從c1_Year完全刪除這些元素。

你可能想要

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)) 
    }
  } 

但是,我看到您已經在使用ddply ,因此您可以避免很多重復。 ddply(c1, .(Year), ...)c1分成唯一的年份。

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 the 'U' col if no '2' interval
                if (all(o$Interval != 2)) {
                    o <- rbind(o,
                               list(o$ComplexId, NA, 0, o$Year, 'U', 2))
                }
                # return the resulting dataframe
                o
            })

我將您的rbind(.., c(...))rbind(.., list(...))以避免將所有內容都轉換回字符串( c這樣做是因為c無法處理多種不同類型) 。

否則,代碼與您的代碼幾乎相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM