Как я могу использовать один и тот же идентификатор inputId в нескольких uiOutputs в R Shiny?

#r #shiny #uioutput #renderui

Вопрос:

Я пишу приложение, которое будет использоваться для ввода данных из бумажных форм в базу данных SQL. Данные взяты из записей о поимке диких животных и будут помещены в одну таблицу, поэтому разные формы имеют много одинаковых полей (например, вес, возраст, вид и т. Д.), Но некоторые формы имеют разные поля или одни и те же поля в другом порядке. Я не хочу, чтобы были видны неиспользуемые поля, и я хочу, чтобы приложение Shiny соответствовало порядку полей в листе данных, чтобы пользователь мог просто просматривать вкладки. Итак, у меня есть uiOutput для каждого вида, который отображается на основе видов, первоначально выбранных из меню. Затем, в пределах этих uiOutput s, другие входные данные, включая selectInput s, где выбор зависит от выбранного вида.

Поскольку многие поля одинаковы, я хочу, чтобы в конце был только один фрейм данных, который использует все входные данные, независимо от выбранного вида, а не фрейм данных медведя, фрейм данных лося и т. Д. Таким образом, input$Age будет отображаться несколько раз , а не input$bearAge input$elkAge каждый раз, когда он отображается один раз. Тогда, в конце концов, у меня был бы фрейм данных , который является entrydata <- data.frame(Age = input$Age) , а не bearentrydata <- data.frame(Age = input$bearAge) elkentrydata <- data.frame(Age = input$elkAge) , и т. Д.

Проблема в том, что shiny, похоже, действительно не нравится, когда одно и то же входное значение используется снова и снова, и оно случайным образом перестанет распознавать новое input$Age для вида 1, затем снова начнет распознавать его для вида 2, а затем снова будет работать для вида 1. Я поместил заявление о печати внутрь observeEvent(input$Age, {}) для проверки. Я попытался исправить это с choices = someAgeVector помощью , где someAgeVector обновления внутри observeEvent(input$GameID,{}) и происходит то же самое, что заставляет меня думать, что это проблема с повторным использованием одного и того же идентификатора.

Есть ли способ, чтобы один и тот же ввод отображался несколько раз?

Вот упрощенная версия приложения:

 library(shiny)

game <- c('', 'Black_Bear', 'Elk', 'Mule_Deer')

## age class data frame
ages <- read.table(header = T, text = "
    Age_Class     Game
    Cub           Black_Bear
    Yearling      Black_Bear
    Subadult      Black_Bear
    Adult         Black_Bear
    6mo           Elk
    Yearling      Elk
    2-9yr_old     Elk
    10-14yr_old   Elk
    >15yr_old     Elk
    Neonate       Mule_Deer
    Fawn          Mule_Deer
    Yearling      Mule_Deer
    Adult         Mule_Deer
    Unknown       Mule_Deer
")
ui <- fluidPage(
  
  selectInput(inputId = 'GameID', label = 'Game', choices = game),
  
  uiOutput(outputId = 'bearUI'),
  uiOutput(outputId = 'elkUI'),
  uiOutput(outputId = 'deerUI'),
)

server <- function(input, output, session) {
  
  observeEvent(input$Age, {
    print(input$Age)
  })
  
  output$bearUI <- renderUI({
    req(input$GameID == 'Black_Bear')
    selectInput(inputId = 'Age', label = 'Age', choices = c(ages[ages$Game == input$GameID,]$Age_Class))
  })
  
  output$elkUI <- renderUI({
    req(input$GameID == 'Elk')
    selectInput(inputId = 'Age', label = 'Age', choices = c(ages[ages$Game == input$GameID,]$Age_Class))
  })
  
  output$deerUI <- renderUI({
    req(input$GameID == 'Mule_Deer')
    selectInput(inputId = 'Age', label = 'Age', choices = c(ages[ages$Game == input$GameID,]$Age_Class))
  })
  
}

shinyApp(ui = ui, server = server)
 

Комментарии:

1. Идентификаторы должны быть уникальными на странице. Это связано с тем, что они реализованы как фактические атрибуты HTML-идентификатора на узлах. Веб — браузеры плохо справляются с дубликатами идентификаторов. Для лучшей стратегии попробуйте что-то вроде блестящих модулей , в которых вы можете создавать элементы «пространства имен», чтобы у вас не было конфликтующих идентификаторов. Но в данном случае я не уверен, почему каждая игра получает свой собственный рендеруй. Похоже, вам нужно только одно значение для возраста, так как весь код в каждой группе одинаков.

2. @MrFlick спасибо тебе! Как я объяснил в вопросе, каждая игра получает свою собственную форму, потому что бумажная форма, используемая для ввода данных, отличается для каждого животного (присутствует разный порядок и не все одинаковые поля), и она должна быть как можно более упрощенной, потому что она будет использоваться сотни раз в год многими разными техниками, поэтому все, что не очень понятно, может вызвать большие проблемы. Я не уверен, как отметить ваш комментарий как правильный ответ, поэтому я вставляю его в поле для ответов и помечаю как ответ, надеюсь, это правильный этикет.

Ответ №1:

Согласно @MrFlick : идентификаторы должны быть уникальными на странице. Это связано с тем, что они реализованы как фактические атрибуты HTML-идентификатора на узлах. Веб — браузеры плохо справляются с дубликатами идентификаторов. Для лучшей стратегии попробуйте что-то вроде блестящих модулей, в которых вы можете создавать элементы «пространства имен», чтобы у вас не было конфликтующих идентификаторов.