Где я могу вставить индикатор выполнения во вложенный цикл? - PullRequest
0 голосов
/ 10 февраля 2019

У меня есть вложенный цикл 'for' в R, который работает в большом фрейме данных (более 80 000 объектов из более чем 6000 переменных) и присваивает значение новому столбцу на основе значений в других переменных.

Из-за размера фрейма данных и того факта, что я тестирую несколько изменений в циклах, я хотел бы вставить индикатор выполнения, чтобы у меня было больше представление о том, сколько могут длиться циклы.

ИтакДо сих пор я пробовал это:

# create an example dataset
id <- c(1,2,3,4,5,6,7,8,9,10)
capital1 <- replicate(1,sample(0:100,10,rep=TRUE))
capital2 <- replicate(1,sample(0:100,10,rep=TRUE))
capital3 <- replicate(1,sample(0:100,10,rep=TRUE))
capital4 <- replicate(1,sample(0:100,10,rep=TRUE))
capital5 <- replicate(1,sample(0:100,10,rep=TRUE))
capital6 <- replicate(1,sample(0:100,10,rep=TRUE))
capital7 <- replicate(1,sample(0:100,10,rep=TRUE))
capital8 <- replicate(1,sample(0:100,10,rep=TRUE))
capital9 <- replicate(1,sample(0:100,10,rep=TRUE))
capital10 <- replicate(1,sample(0:100,10,rep=TRUE))

data <- data.frame(id, capital1, capital2, capital3, capital4,
capital5, capital6, capital7, capital8, capital9, capital10)

# create new column to populate with results of loop
nrows<-length(data[,1])
AFT<-rep("N_A",nrows)

# set up progress bar for loop
total <- nrows
pb <- txtProgressBar(min = 0, max = length(total), style = 3)

# for loop
for (i in c(1:nrows)) { 

    Sys.sleep(.1)

    # Mask out waterbodies and dense artifical (urban) areas
    if (data$capital1[i]>70) {
        AFT[i]<-'water.urban'} 

    if (data$capital2[i]>70) {
        AFT[i]<-'water.urban'} 

    if (data$capital3[i]+data$capital4[i]>=60){
        AFT[i]<-'multi.mixed'}
    if (data$capital4[i]>70) {
        AFT[i]<-'multi.nb'}

    # etc. (10+ more loops assigning different AFTs)

    # print progress as loop runs
    cat("\r", i, "of", 10, "\r") 
    flush.console()

}

В данный момент код выполняется, но индикатор выполнения, кажется, сразу завершается, в то время как фактический процесс продолжается.Я полагаю, я не помещаю индикатор выполнения в нужное место в цикле?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Вместо того, чтобы пытаться перебрать более 80 000 строк с помощью цикла for, используйте мощность векторизованных возможностей R.Вы можете выбрать, какие значения AFT обновлять, используя функцию which.Функция which возвращает вектор индексов, где сравнение ИСТИНА.Это обеспечит повышение производительности в 1000 раз по сравнению с циклом for, что делает индикатор выполнения устаревшим.

Например, ваши назначения будут выглядеть примерно так:

AFT[which(data$capital1>70)] <-'water.urban'
AFT[which(data$capital2>70)] <-'water.urban'
AFT[which((data$capital3+data$capital4)>=60)]<-'multi.mixed'
AFT[which(ata$capital4>70)]<-'multi.nb'
0 голосов
/ 10 февраля 2019

, набрав ?txtProgressBar, вы будете перенаправлены в файл справки для функции.Здесь вы увидите две другие функции getTxtProgressBar и setTxtProgressBar.Как видно из их названия, их можно использовать для получения и установки текущего прогресса на любом экземпляре индикатора выполнения.

Для вашего примера попробуйте добавить setTxtProgressBar(pb, i) в том месте внутри цикла for, где вы хотите обновить прогресс,Выбранное место может быть где угодно, в зависимости от того, когда и как часто вы хотите показать прогресс.Например, в вашем конкретном примере индикатор выполнения имеет максимальное значение, которое также используется при итерации i, обновление индикатора выполнения может быть достигнуто в начале цикла for, как показано ниже.

for (i in c(1:nrows)) { 
  setTxtProgressBar(pb, i)
  ...
}
close(pb)

Обратите внимание, как я использую close(pb) после цикла, чтобы отключить индикатор выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...