Включить для итерации l oop в фрейм данных в R - PullRequest
0 голосов
/ 08 апреля 2020

Очень плохо знаком с кодированием. Я пытался ввести значения из итерации для l oop в фрейм данных. Я посмотрел на многие заданные вопросы, но, похоже, они не помогли моей ситуации. Когда my для l oop завершено, my cat () выводит все значения итерации. Я попытался создать фрейм данных, используя имена переменных, как вы можете видеть в коде, однако он выводит только одну строку с последней итерацией. Мне сказали создать фрейм данных до моего for-l oop, чтобы сохранить выходные значения, но я не могу понять это. Если кто-нибудь может показать мне правильный код, который будет очень признателен! Спасибо

Numyears<- 0
NumLynxes<-0
NumHares<-0
flag<- F
NumBabyLynxes<-0
NumBabyHares<-0
NumDeadHares<-0
NumDeadLynxes<-0
NumHaresEaten<-0

while(flag !=T) {

ask <-readline(prompt = "Simulate the population of Lynx and Hares in Canada?
Type 1 for yes, Type anything else to exit:")
response<- as.integer(ask)

 if (response ==1) {
 variable1 <- readline(prompt = "Input the number of years for the simulation sample:")
 Numyears <- as.integer(variable1)
 variable2 <- readline(prompt="Enter the number of Lynxes in this simulation:")
 NumLynxes <- as.integer(variable2)
 variable3 <-readline("Enter the number of Hares in this simulation:")
 NumHares <-as.integer(variable3)

  DF <- data.frame(Numyears,NumHares,
                 NumLynxes,NumBabyHares,
                 NumBabyLynxes,
                 NumDeadHares,
                 NumDeadLynxes,
                 NumHaresEaten,stringsAsFactors = F)

  for (years in 1:Numyears) {

   if ( (NumLynxes/NumHares) < 0.20) {

    NumDeadLynxes<-round(NumLynxes * 0.02)
    NumBabyLynxes <- round(0.15*NumLynxes)
   }

   if ((NumLynxes/NumHares) >= 0.20) {
    NumDeadLynxes <- round(0.50*NumLynxes)
    NumBabyLynxes <- round(0.15*NumLynxes)
   }


   NumBabyHares<- round(0.75*NumHares)
   NumDeadHares <- round(NumDeadHares*0.01)
   NumHaresEaten <- round((NumLynxes*NumHares)*0.025)

   years <- years 
   NumLynxes <- ((NumLynxes + NumBabyLynxes) - NumDeadLynxes)
   NumHares <- ((NumHares + NumBabyHares) - (NumHaresEaten + NumDeadHares))

   if ((NumLynxes/NumHares) < 0){
    break
   }

   cat("Year  #Hares  #Lynxes  babyH  babyL  deadHare  deadLynx","\n",
      years," ","\t",NumHares," ","\t",NumLynxes, " ","\t",NumBabyHares, 
      " ","\t",NumBabyLynxes,"   ","\t",NumDeadHares," ","\t",NumDeadLynxes,
      " ", "\t",NumHaresEaten) 

  } 

 } else{
   flag <- T
 }
}
 DF

1 Ответ

1 голос
/ 08 апреля 2020

Взгляните на этот метод вместо этого.

  1. Я предварительно выделил весь DF с таким количеством строк, сколько необходимо. Это предотвращает проблему «растущих объектов», о которой говорится в главе 2 R Inferno .

    Я включаю начальные условия в data.frame. Хотя это и не является абсолютно необходимым, в дальнейшем это значительно упрощает расчеты. Без него нам бы пришлось рассчитать следующие популяции с помощью if (row == 1) { calc_one_way; } else { calc_another_way; }, что кажется достаточно простым, но плохо читается. Если вам не нравятся начальные условия в первом ряду, вы всегда можете удалить их в самом конце с помощью DF[-1,].

  2. Хотя технически мы можем использовать attach(DF) во избежание необходимости ссылаться на DF$ каждый раз, я настоятельно рекомендую это: это поощряет некоторые небрежные привычки, и может и будет иногда вызывать проблемы, если вы не будете очень осторожны.

  3. I Я делаю вывод, что мы растем (или едим) население из года в год, поэтому мы устанавливаем население в следующем году, основываясь на численности населения в этом году и его поведении. При этом я ссылаюсь на цифры этого года с [row] и устанавливаю цифры на следующий год с [row+1]. Всякий раз, когда выполняется индексация таким образом, следует соблюдать осторожность, чтобы никогда не было go слишком низким ([0] - ошибка в R) или слишком высоким. В этом случае, поскольку у нас есть NumYears + 1 количество строк (я начинаю с года 0 в строке 1), и мы выполняем итерацию только от строки 1 (год 0) до NumYears (nrow(DF) - 1), мы хорошо используя [row] и [row+1] для индексов строк.

    Примечание: мы начинаем с row из 1, что отражает year 0 (начальные условия). Это было мое предположение и полностью зависит от вас.

flag <- FALSE

while(flag != TRUE) {

  ask <-readline(prompt = "Simulate the population of Lynx and Hares in Canada?
Type 1 for yes, Type anything else to exit:")
  response <- as.integer(ask)

  if (response == 1) {

    variable1 <- readline(prompt = "Input the number of years for the simulation sample:")
    NumYears <- as.integer(variable1)
    variable2 <- readline(prompt="Enter the number of Lynxes in this simulation:")
    NumLynxes <- as.integer(variable2)
    variable3 <- readline("Enter the number of Hares in this simulation:")
    NumHares <- as.integer(variable3)

    zeroes <- rep(0, NumYears + 1)
    DF <- data.frame(
      Year = c(0, seq_len(NumYears)),
      NumHares = c(NumHares, zeroes[-1]),
      NumLynxes = c(NumLynxes, zeroes[-1]),
      NumBabyHares = zeroes, NumBabyLynxes = zeroes,
      NumDeadHares = zeroes, NumDeadLynxes = zeroes,
      NumHaresEaten = zeroes)

    for (row in seq_len(NumRows)) {

      if ( (DF$NumLynxes[row] / DF$NumHares[row]) < 0.20) {
        DF$NumDeadLynxes[row + 1] <- round(DF$NumLynxes[row] * 0.02)
        DF$NumBabyLynxes[row + 1] <- round(0.15 * DF$NumLynxes[row])
      } else {
        DF$NumDeadLynxes[row + 1] <- round(0.50 * DF$NumLynxes[row])
        DF$NumBabyLynxes[row + 1] <- round(0.15 * DF$NumLynxes[row])
      }


      DF$NumBabyHares[row] <- round(0.75 * DF$NumHares[row])
      DF$NumDeadHares[row] <- round(DF$NumDeadHares[row] * 0.01)
      DF$NumHaresEaten[row] <- round((DF$NumLynxes[row] * DF$NumHares[row]) * 0.025)

      DF$NumLynxes[row + 1] <- ((DF$NumLynxes[row] + DF$NumBabyLynxes[row]) - DF$NumDeadLynxes[row])
      DF$NumHares[row + 1] <- ((DF$NumHares[row] + DF$NumBabyHares[row]) - (DF$NumHaresEaten[row] + DF$NumDeadHares[row]))

      if (DF$NumLynxes[row] <= 0) {
        break
      }

      print(DF[row + 1,])

    }

  } else{
    flag <- TRUE
  }
}

В конце концов, могут происходить и другие вещи: когда я начинаю с 10 каждого зайца / рыси, тогда рост немного взрывной ...

DF
#    Year NumHares NumLynxes NumBabyHares NumBabyLynxes NumDeadHares NumDeadLynxes NumHaresEaten
# 1     0       10        10            8             0            0             0             2
# 2     1       16        10           12             2            0             5             4
# 3     2       24         7           18             2            0             5             4
# 4     3       38         4           28             1            0             4             4
# 5     4       62         1           46             1            0             0             2
# 6     5      106         2           80             0            0             0             5
# 7     6      181         2          136             0            0             0             9
# 8     7      308         2          231             0            0             0            15
# 9     8      524         2          393             0            0             0            26
# 10    9      891         2          668             0            0             0            45
# 11   10     1514         2         1136             0            0             0            76
# 12   11     2574         2         1930             0            0             0           129
# 13   12     4375         2         3281             0            0             0           219
# 14   13     7437         2         5578             0            0             0           372
# 15   14    12643         2         9482             0            0             0           632
# 16   15    21493         2        16120             0            0             0          1075
# 17   16    36538         2        27404             0            0             0          1827
# 18   17    62115         2        46586             0            0             0          3106
# 19   18   105595         2        79196             0            0             0          5280
# 20   19   179511         2       134633             0            0             0          8976
# 21   20   305168         2            0             0            0             0             0

Веселитесь.

...