如何修复在遍历整个数据帧之前过早停止的功能循环

时间:2019-04-03 12:47:44

标签: r function loops

因此,我正在运行一个函数,该函数获取植物上的平均感染水平,并计算出一段时间内该植物已被感染的程度。称为疾病进展曲线下的面积。该功能有效,很好,我现在尝试创建一个循环以针对每个工厂进行计算并将其存储在数据帧中。但是,循环在应该停止之前就停止了吗?

该函数可以手动使用,即一次将Plant_ID放入一个,但是循环似乎在遍历整个数据帧之前停止了。我真的迷失了为何停止

功能如下:

audpc <- function(df,plant_ID){
  #subset the df so that only rows with the tree.ID of interest are kept
  df <- subset(df, Plant_ID == plant_ID)
  # assign time.period and disease.severity vectors for use below
  time.period <- df$Week
  disease.severity <- df$Upper_percentage
  #n is the length of time.period
  n <- length(time.period)
  #meanvec is the vector
  #that will contain the mean percent infection
  #it is initialized containing -1 for all entries
  #this sort of initialization is sometimes useful
  #  for debugging
  meanvec <- matrix(-1,(n-1))
  #intvec is the vector that will contain the length of
  #   time between sampling dates
  intvec <- matrix(-1,(n-1))
  for(i in 1:(n-1)){
    #the ith entry in meanvec is replaced with the
    #   mean percent infection
    #between sample time i and sample time i+1
    meanvec[i] <- mean(c(disease.severity[i],                   
                         disease.severity[i+1]))
    #the ith entry in intvec is replaced with the length
    # of the time interval between time i and time i+1
    intvec[i] <- time.period[i+1] - time.period[i]
  }
  #the two vectors are multiplied together
  # one entry at a time
  infprod <- meanvec * intvec
  #the sum of the entries in the resulting vector
  #   gives the AUDPC
  sum(infprod)
}
## end of function

然后是下面的破环

#

## make an "output" dataframe to store AUDPC values
out <- subset(DF1, Week == 31) #we want each tree.ID just once
#add a column of NAs to replace with AUDPC values
out$AUDPC <- rep(NA, length(out[,1])) 

#run the function on a loop for each tree.ID in your output df
for (i in 1:length(out[,1])){
  tree.ID <- DF1$Plant_ID[i] #assign tree.ID for use in audpc func

  #n = number of observations (timepoints) of PM infection
  n <- length(subset(DF1, Plant_ID == tree.ID)$Week)
  #if n > 2, run the output func and put the value into the AUDPC column 
  # of your output df that corresponds to the current tree.ID
  out$AUDPC[which(out$Plant_ID == tree.ID)] <- ifelse(
    n > 2, audpc(DF1, tree.ID), NA)
}

## remove NA values
out.na <- na.omit(out)
dim(out)

我的数据的一个子类别是通过dput在下面,它在计算机上进行9次观察后停止了吗?

DF1<- dput(structure(list(Plant_ID = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 
2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 7L, 7L, 7L, 8L, 
8L, 8L, 9L, 9L, 9L, 10L, 10L, 10L, 11L, 11L, 11L, 12L, 12L, 12L, 
12L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 16L, 
16L, 16L, 16L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 19L, 19L, 
19L, 19L, 20L, 20L, 20L, 20L, 21L, 21L, 21L, 21L, 22L, 22L, 22L, 
23L, 23L, 23L, 23L, 24L, 24L, 24L, 25L, 25L, 25L, 25L, 26L, 26L, 
26L, 27L, 27L, 27L, 27L, 28L, 28L, 28L, 28L, 29L, 29L, 29L), .Label = c("1", 
"10", "100", "101", "102", "103", "104", "105", "106", "107", 
"108", "11", "111", "112", "113", "114", "115", "116", "117", 
"118", "119", "12", "120", "121", "123", "124", "125", "126", 
"127", "128", "129", "13", "130", "131", "132", "134", "135", 
"136", "137", "138", "139", "14", "140", "141", "142", "143", 
"144", "146", "147", "148", "15", "151", "152", "153", "154", 
"155", "156", "157", "159", "16", "162", "166", "168", "169", 
"17", "170", "172", "173", "174", "175", "176", "177", "178", 
"179", "18", "180", "181", "182", "183", "184", "185", "186", 
"187", "188", "19", "190", "191", "192", "193", "194", "195", 
"196", "198", "199", "2", "20", "200", "201", "202", "203", "204", 
"205", "206", "207", "208", "209", "21", "211", "214", "215", 
"218", "22", "221", "222", "223", "224", "225", "226", "227", 
"228", "229", "23", "230", "231", "232", "233", "234", "235", 
"236", "237", "238", "239", "24", "240", "241", "242", "243", 
"244", "245", "246", "247", "248", "249", "25", "250", "251", 
"252", "253", "254", "255", "256", "257", "258", "259", "26", 
"260", "261", "262", "263", "264", "266", "267", "268", "269", 
"27", "271", "272", "273", "276", "277", "278", "279", "28", 
"280", "281", "282", "283", "284", "285", "286", "287", "288", 
"289", "29", "290", "291", "292", "293", "294", "295", "296", 
"297", "298", "299", "3", "30", "300", "301", "302", "303", "304", 
"305", "306", "307", "308", "309", "31", "310", "311", "312", 
"313", "314", "315", "316", "317", "319", "32", "320", "321", 
"322", "323", "324", "325", "326", "327", "328", "329", "33", 
"330", "331", "332", "333", "334", "335", "336", "337", "338", 
"339", "34", "340", "341", "342", "343", "344", "345", "346", 
"347", "348", "349", "35", "350", "351", "352", "353", "354", 
"355", "356", "357", "358", "359", "36", "360", "361", "362", 
"363", "364", "365", "366", "367", "368", "369", "370", "371", 
"372", "373", "374", "375", "376", "377", "378", "38", "380", 
"382", "386", "387", "388", "389", "39", "390", "391", "392", 
"393", "394", "395", "396", "397", "398", "399", "4", "40", "400", 
"401", "402", "403", "404", "405", "406", "407", "408", "409", 
"41", "410", "411", "412", "413", "415", "416", "417", "418", 
"419", "42", "420", "421", "422", "423", "424", "425", "426", 
"427", "428", "429", "43", "430", "431", "432", "433", "435", 
"436", "437", "438", "439", "44", "441", "442", "444", "445", 
"448", "451", "452", "453", "454", "456", "457", "458", "459", 
"46", "460", "461", "462", "463", "464", "467", "468", "47", 
"470", "471", "475", "476", "477", "478", "479", "480", "481", 
"482", "483", "486", "487", "49", "492", "493", "494", "496", 
"497", "499", "5", "50", "500", "501", "502", "503", "504", "505", 
"506", "507", "508", "509", "51", "510", "511", "512", "516", 
"517", "518", "519", "520", "521", "522", "523", "524", "525", 
"526", "527", "528", "529", "530", "531", "532", "533", "534", 
"535", "536", "537", "539", "54", "541", "543", "544", "545", 
"546", "547", "548", "55", "551", "552", "553", "554", "555", 
"556", "557", "558", "559", "56", "561", "562", "563", "564", 
"565", "566", "567", "568", "569", "57", "570", "571", "572", 
"573", "574", "575", "576", "577", "578", "579", "58", "580", 
"581", "582", "584", "585", "586", "587", "588", "589", "59", 
"590", "591", "592", "593", "594", "597", "599", "6", "60", "601", 
"602", "603", "604", "606", "607", "608", "609", "61", "610", 
"611", "612", "613", "614", "615", "616", "617", "618", "619", 
"62", "620", "621", "622", "623", "624", "625", "626", "627", 
"628", "629", "63", "630", "631", "632", "633", "634", "635", 
"636", "637", "639", "64", "640", "641", "642", "643", "644", 
"645", "646", "647", "648", "649", "650", "651", "652", "653", 
"654", "658", "659", "66", "665", "666", "667", "67", "671", 
"674", "675", "676", "678", "68", "680", "682", "683", "685", 
"686", "689", "69", "690", "697", "698", "7", "70", "702", "703", 
"704", "705", "706", "707", "708", "71", "710", "711", "713", 
"714", "716", "717", "718", "719", "72", "720", "721", "723", 
"724", "726", "727", "728", "729", "73", "730", "731", "732", 
"733", "734", "735", "736", "737", "738", "739", "74", "740", 
"741", "742", "743", "744", "745", "747", "748", "749", "75", 
"750", "751", "752", "754", "755", "756", "757", "758", "759", 
"76", "760", "762", "763", "764", "765", "766", "767", "768", 
"769", "77", "770", "772", "775", "776", "777", "778", "779", 
"78", "780", "79", "8", "80", "81", "82", "83", "84", "85", "86", 
"87", "88", "9", "90", "91", "93", "94", "95", "97", "98", "99"
), class = "factor"), Upper_percentage = c(0, 0, 0, 0, 0, 1.42857142857143, 
2, 0, 0, 0.15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.222222222222222, 0.333333333333333, 
0.444444444444444, 1.66666666666667, 0, 0, 0, 1.14285714285714, 
0, 0, 0.8, 0, 0, 0, 0, 1.33333333333333, 2.6, 2.63636363636364, 
6.81818181818182, 0, 0, 0.1, 5.73684210526316, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.285714285714286, 
6, 0, 0.333333333333333, 0.333333333333333, 3.33333333333333, 
0, 0.5, 2.875, 0, 0, 13.6666666666667, 21.5, 0.6, 0.6, 8.2, 25.6, 
0, 0, 0.25), Week = c(26L, 27L, 29L, 31L, 26L, 29L, 31L, 27L, 
29L, 31L, 27L, 29L, 31L, 27L, 29L, 31L, 27L, 31L, 27L, 29L, 31L, 
27L, 29L, 31L, 27L, 29L, 31L, 27L, 29L, 31L, 27L, 29L, 31L, 26L, 
27L, 29L, 31L, 26L, 27L, 29L, 31L, 26L, 27L, 29L, 31L, 27L, 29L, 
31L, 26L, 27L, 29L, 31L, 26L, 27L, 29L, 31L, 26L, 27L, 29L, 31L, 
26L, 27L, 29L, 31L, 26L, 27L, 29L, 31L, 26L, 27L, 29L, 31L, 27L, 
29L, 31L, 26L, 27L, 29L, 31L, 27L, 29L, 31L, 26L, 27L, 29L, 31L, 
27L, 29L, 31L, 26L, 27L, 29L, 31L, 26L, 27L, 29L, 31L, 27L, 29L, 
31L)), row.names = c(NA, 100L), class = "data.frame"))

示例数据中有29种不同的Plant_ID代码,因此我应该收到AUDPC得分的29项观察结果。相反,我接收到29个观测值,但其中大多数为NA。

预先感谢您抽出宝贵的时间来解决我的问题,如果我不清楚我在哪里,请原谅!

3 个答案:

答案 0 :(得分:0)

我相信您的问题来自循环的开始

Declare @test varchar(100)='images/test.jpg'
Select REPLACE(RIGHT(@test,charindex('/',reverse(@test))-1),'.jpg','')

您需要写:

for(i in 1:(n-1)){

很明显,data.frame是您当前正在使用的数据集的名称。

让我知道怎么回事

答案 1 :(得分:0)

也许您需要nrow函数而不是length函数。有关这两个功能之间的区别的讨论,请参见此处的帖子:

why nrow(dataframe) and length(dataframe) in r give different results?

编辑 实际上,该错误似乎在您的循环中:

for (i in 1:length(out[,1])){
  tree.ID <- DF1$Plant_ID[i] #assign tree.ID for use in audpc func

  #n = number of observations (timepoints) of PM infection
  n <- length(subset(DF1, Plant_ID == tree.ID)$Week)
  #if n > 2, run the output func and put the value into the AUDPC column 
  # of your output df that corresponds to the current tree.ID
  out$AUDPC[which(out$Plant_ID == tree.ID)] <- ifelse(
    n > 2, audpc(DF1, tree.ID), NA)
}

您正在遍历out数据框中的i行。但是,循环的第一行将df数据帧的第i行用作参考点。我认为它应该使用out数据框的第i行。将循环中的第一行更改为:

  tree.ID <- out$Plant_ID[i] #assign tree.ID for use in audpc func

答案 2 :(得分:0)

谢谢你们的评论!我发现是否要改变

for (i in 1:length(out[,1])){

要代替整个OG数据帧的长度(如下所示),那么它似乎可以工作

for (i in 1:length(DF1[,1])){

但是我真的不明白为什么这样做有效,但是无论如何我们都在这里!

再次感谢!