【问题标题】:Display and Hide dataframe in Shiny在 Shiny 中显示和隐藏数据框
【发布时间】:2017-11-15 13:36:40
【问题描述】:
# ui.R

shinyUI(
 fluidPage(
    titlePanel("Make a data frame and display"),
    fluidRow(column(4,selectInput('types', 'Select the type',c("Basketball","Soccer")))),
    uiOutput('typeChange'),
    mainPanel(dataTableOutput('displayDf'))
 )
)

我正在尝试接受用户输入并将数据存储到数据框中。然后,我想在用户继续添加记录时同时显示数据框。上面的代码让用户在 BasketballSoccer 之间进行选择

# server.R
# Create a function to initiate and clear global variables

clear_all <- function(){
z <<- c()
z1 <<- c()
z2 <<- c()
z3 <<- c()
}
clear_all()

shinyServer(function(input, output, session) {

# make additional ui depending on the sport selected.
output$typeChange <- renderUI({
    if (input$types=="Basketball"){
        clear_all()
        fluidRow(
        column(4,textInput("v1","Player name")),
        column(4,selectInput("v2", "Age:",c("20","25","30"))),
        column(4,actionButton("add", "Add the above player")))
    }else if (input$types=="Soccer"){
        clear_all()
        fluidRow(
        column(4,textInput("v1","Player name")),
        column(4,selectInput("v2", "Age",c("20","25","30"))),
        column(4,selectInput("v3", "Income:",c("100","125","150"))),
        column(4,actionButton("add", "Add the above player")))
    }else{}
})

# if a user adds a player, update the dataframe and display
observeEvent(input$add, {
    if (input$types=="Basketball"){
        z1 <<- c(z1,input$v1)
        z2 <<- c(z2,input$v2)
        z<<- data.frame(Player=z1,Age=z2)
    }else if (input$types=="Soccer"){
        z1 <<- c(z1,input$v1)
        z2 <<- c(z2,input$v2)
        z3 <<- c(z3,input$v3)
        z<<- data.frame(Player=z1,Age=z2,Income=z3)
    }

    output$displayDf=renderDataTable(z)
})
})

服务器端代码根据选择的运动创建新文本和选择输入。我正在尝试创建的功能是,在选择一项运动后,用户可以输入其他输入并添加玩家。只要用户没有选择其他运动,就应该显示用户添加的球员列表。一旦用户更改了运动,数据框将是空的,并且不会显示之前运动的任何内容。

我面临的问题是,如果我在篮球中添加 3 名球员,然后将我的首选更改为足球,我仍然会看到篮球数据,直到我添加一名足球运动员。我希望在更改运动后立即隐藏显示的数据框。还附上相同的截图。请指教。

【问题讨论】:

  • 我很确定问题是z 没有更新为input$types。 (z 仅通过input$v1 更新至input$v3)。当input$types 改变时,它查询server 端,它通过observeEvent 查找(因为它包含input$types),但是z 没有改变,因此renderDataTable 什么也不做。使z 直接响应input$types 应该可以解决您的问题。

标签: r shiny


【解决方案1】:

如果您将数据表放在反应式输出中,您的问题就可以解决,这样它总是显示input$type 所说的内容,即:

  1. 创建一个反应值列表,tables,其长度为 2,分别存储篮球和足球表格。
  2. 根据input$type的内容显示其中之一。

我在解决这个问题时整理了您的应用程序(1. 不要使用重复的输入 ID,2. 使用全局变量不像使用反应式那样干净,3. 使用条件面板):

library(shiny)
library(plotly)
library(shinyjs)

ui <- shinyUI(
  fluidPage(
    useShinyjs(),
    titlePanel("Make a data frame and display"),
    fluidRow(column(4,selectInput('types', 'Select the type',c("Basketball","Soccer")))),
    fluidRow(column(width=8,
                    column(4, textInput("v1","Player name")),
                    column(4, selectInput("v2", "Age:",c("20","25","30"))),
                    conditionalPanel(condition="input.types == 'Soccer'",
                                     column(4, selectInput("v3", "Income:",c("100","125","150"))))),
                    column(1, actionButton("add", "Add the above player"))),
    mainPanel(dataTableOutput('displayDf'))
  )
)


server <- shinyServer(function(input, output, session) {

  tables <- reactiveValues(basketball = data.frame(Player = character(), Age = numeric()),
                           soccer     = data.frame(Player = character(), Age = numeric(), Income = double()))

# if a user adds a player, update the dataframe and display
  observeEvent(input$add, {
    if (input$types=="Basketball"){
      oldVals <- tables$basketball
      tables$basketball <- rbind(oldVals, data.frame(Player = input$v1, Age = input$v2))
    }else if (input$types=="Soccer"){
      oldVals <- tables$soccer
      tables$soccer <- rbind(oldVals, data.frame(Player = input$v1, Age = input$v2, Income = input$v3))
    }

    # reset the input values
    reset("v1")
    reset("v2")
    reset("v3")
  })

  # display the appropriate table
  output$displayDf <- renderDataTable({
    if (input$types=="Basketball") tables$basketball else tables$soccer
  })
})

shinyApp(ui, server)

【讨论】:

  • 非常感谢您的帮助。我看到在切换运动时,数据框不会删除所有行(就像我在代码中使用 clear_all() 函数所做的那样。感谢您对代码的改进。您能否帮助我清空切换运动的数据框?
  • 请说明。每次回到“篮球”时,您希望 Basketballtable 为空?
  • 虽然我看不出有什么意义,还是把这个加到服务器上吧:observeEvent(input$types, { tables$basketball &lt;- data.frame(Player = character(), Age = numeric()); tables$soccer &lt;- data.frame(Player = character(), Age = numeric(), Income = double()) })
猜你喜欢
  • 2017-04-25
  • 2018-05-12
  • 2021-06-08
  • 2016-05-10
  • 2019-03-18
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多