Итерация внутри fluidRow () с операторами for и if в R - PullRequest
0 голосов
/ 04 августа 2020

Я пытаюсь использовать fluidRow внутри bs4TabItem, который будет иметь максимум 3 элемента bs4UserCard. FluidRows следует строить динамически внутри a для l oop и макс. 3 bs4UserCard также следует создавать динамически внутри a для l oop. Ниже приведен фрагмент кода. Я пробовал код как в пользовательском интерфейсе, так и в разделе «Сервер» на основе других рекомендаций, но он все еще не работает.

# Get number of rows from dataset
records = nrow(candidatesDF)

# Each row will have max. 3 items
numRows = ceiling(nrow(candidatesDF) / 3)
numRows = c(1:numRows)

count = 0
offset = 3

candidates =  bs4TabItem(tabName = "candidates",
  for (row in numRows) {
    fluidRow(
      if (records < offset) {
        offset = records
      }
      for (column in 1:offset) {
        count = count + 1

        # Convert the names to a more legible format
        name = explode(candidatesDF[count, "Candidate"], sep = ", ")
        name = paste0(name[2], ' ', name[1])
        name = capitalizeStrings(name, all.words = TRUE, lower.back = TRUE)

        # Convert the names to the img name format
        imgName = explode(name, sep = " ")
        imgName = tolower(implode(imgName, "_"))
        imgUrl = paste0("img/", imgName, ".png")

        # Create a user card on each iteration.
        bs4UserCard(
          title = name,
          subtitle = candidatesDF[count, "Party"],
          type = NULL,
          width = 4,
          src = imgUrl,
          status = "danger",
          closable = TRUE,
          elevation = 4,
          imageElevation = 4,
          fluidRow(
            column(
              width = 4,
              descriptionBlock(header = "District",
               text = capitalizeStrings(candidatesDF[count, "District"],
                      all.words = TRUE, lower.back = TRUE ))
            ),
            column(
              width = 4,
              descriptionBlock(header = "Votes",
               text = candidatesDF[count, "Votes"])
            ),
            column(
              width = 4,
              descriptionBlock(header = "Result",
               text = candidatesDF[count, "Result"], right_border = FALSE)
            )
          )
        )

        records = records - 1
      }
    ) 
  } 
)

С оператором if я получаю эту ошибку

Possible missing comma at:
87:  for (row in fluidRows) {
              ^

Если я удалю оператор if только для целей тестирования, я получаю эту ошибку

Warning: Error in explode: Assertion on 'x' failed: May not be NA.

Я не уверен, что x in explode является NA, потому что у меня нет значений NA в наборе данных. Когда я запускаю код построчно для проверки функции разнесения, возвращается ожидаемый результат, поэтому я не понимаю, почему NA.

Тем не менее, моя цель - создать x количество fluidRows с максимальным количеством 3 элементов в каждой строке с информацией об элементах, динамически генерируемых из набора данных. ############################################### ##################### Я обновил код, чтобы отразить предложение использовать lapply ().

# Get number of rows from dataset
records = nrow(candidatesDF)

# Each row will have max. 3 items
numRows = ceiling(nrow(candidatesDF) / 3)
numRows = c(1:numRows)

count = 0
offset = 3

checkOffset = function(records, offset) {
  if (records < offset) {
    offset = records
  }
  
  return(offset) 
}


candidates =  bs4TabItem(tabName = "candidates",
 lapply(numRows, function(r) {
   fluidRow(
     lapply(1:checkOffset(records, offset), function(c) {
       count = count + 1
       print(count)
       # Convert the names to a more legible format
       name = explode(candidatesDF[count, "Candidate"], sep = ", ")
       name = paste0(name[2], ' ', name[1])
       name = capitalizeStrings(name, all.words = TRUE, lower.back = TRUE)

       # Convert the names to the img name format
       imgName = explode(name, sep = " ")
       imgName = tolower(implode(imgName, "_"))
       imgUrl = paste0("img/", imgName, ".png")
       
       records = records - 1
       
       # Create a user card on each iteration.
       bs4UserCard(
         title = name,
         subtitle = candidatesDF[count, "Party"],
         type = NULL,
         width = 4,
         src = imgUrl,
         status = "primary",
         closable = TRUE,
         elevation = 4,
         imageElevation = 4,
         fluidRow(
           column(
             width = 4,
             descriptionBlock(header = "District",
              text = capitalizeStrings(candidatesDF[count, "District"],
                     all.words = TRUE, lower.back = TRUE ))
           ),
           column(
             width = 4,
             descriptionBlock(header = "Votes",
              text = candidatesDF[count, "Votes"])
           ),
           column(
             width = 4,
             descriptionBlock(header = "Result",
              text = candidatesDF[count, "Result"], right_border = FALSE)
           )
         )
       )
     })
   )
 })

Хотя это помогло Дело в приближении к желаемому результату, каждая карта в каждой сетке одинакова. Это связано с тем, что переменная count не увеличивается, равно как и переменная записи.

Заранее спасибо.

1 Ответ

0 голосов
/ 05 августа 2020

После переключения for l oop на базу lapply по рекомендации @YBS, моей основной проблемой стало выяснение, почему переменные count и record не сохраняют свои значения после первой итерации lapply.

Ответ - использовать << - для присваивания вместо =. Объяснение можно найти в <a href="/1925742/ne-mogu-izmenit-peremennye-v-bolee-vysokom-obeme"> может не изменять переменные в более высоком диапазоне .

...