【问题标题】:R Shiny Manipulating DatatableR Shiny 操作数据表
【发布时间】:2019-04-07 13:49:42
【问题描述】:

我想先上传一个 CSV 文件,然后根据在侧面板中选择的内容来操作我的数据表的呈现方式。这是我的 CSV 数据示例:

Students Data Table

这是如何工作的,我将首先选择我的部门:如果我是校长,则打印整个数据表。如果我是教师,我只能看到 SubmissionDate、StudentID 和 Class。如果我是学生,我只能看到 SubmissionDate、StudentID 和 Student。

此外,我打算按 SubmissionDate 过滤。无论我是谁,如果我选择一个日期范围,则只会显示日期范围内的那些行。例如,如果我是 A03 Sam,如果我没有选择日期范围,我将看到 2 行。如果我选择一年的日期范围,我只会看到 1 行。

我的问题是: 1. 我的数据表显然无法运行。是因为使用 fread 吗?我收到此错误:“警告:.getReactiveEnvironment()$currentContext 中的错误:没有活动的反应上下文不允许操作。(您试图做一些只能从反应表达式或观察者内部完成的事情。)”

  1. 如何从多个输入中过滤我的数据表?

这是我的 R Shiny 代码:

ui <- fluidPage(
  titlePanel("Students"), 
  sidebarLayout( 
    sidebarPanel(
      fileInput("file1", 
                "Choose CSV File", 
                multiple=TRUE, 
                accept=c( "text/csv", "text/comma-separated-values,text/plain", ".csv")), 
      checkboxInput("header", "Header", TRUE),
      radioButtons("disp", "Display", choices=c(Head="head" , All="all" ), selected="head"), 
      
      tags$hr(), 
      radioButtons("dept", 
                   "Department", 
                   choices=c(Principal="Principal" , Teacher="Teacher" , Student="Student"
      dateRangeInput("dates", "Date Range"), 
      textInput("studentid",
                "StudentID", 
                value="Enter StudentID:" )
) ), 
                         
  mainPanel(tableOutput("contents") ) ) )
  
library(shiny) 
library(data.table) 
server <- function(input,output) { 
  data <- fread(input$file1$datapath, 
                header=input$header, 
                sep=",", 
                quote='"') 
  
  output$contents <- renderDataTable( 
  if(input$disp=="head" ){return(data))} 
  else {return(data)}
  ) 
} 
  
shinyApp(ui, server)

非常感谢!

【问题讨论】:

  • 您好,请参考How To Ask Good question,提出的好问题轻松投票,投票的问题获得更多吸引力以获得好的答案。
  • 您好,最好将这个问题拆分为您遇到的每个问题的最小可重复示例。您现在报告的错误与fread 无关,而是与您的服务器端缺少reactive 有关。 reactive 上下文允许您根据更改的 input$variables 计算新值 - 然后在 render 操作中使用这些新值。您的 input$disp 不在 reactive({ }) 块内,给出您当前的错误。

标签: r shiny


【解决方案1】:

您需要正确设置所有reactive 组件。

此外,如果您希望正确过滤数据,则需要在server 中对其进行操作。

以下是基于您的示例的工作脚本:

library(shiny) 
library(data.table)
library(dplyr)

ui <- fluidPage(
  titlePanel("Students"), 
  sidebarLayout( 
    sidebarPanel(
      fileInput("file1", 
                "Choose CSV File", 
                multiple=TRUE, 
                accept=c( "text/csv", "text/comma-separated-values,text/plain", ".csv")), 
      checkboxInput("header", "Header", TRUE),
      radioButtons("disp", "Display", choices=c(Head="head" , All="all" ), selected="head"), 

      tags$hr(), 
      radioButtons("dept", 
                   "Department", 
                   choices=c(Principal="Principal" , Teacher="Teacher" , Student= "Student")),
      dateRangeInput("dates", "Date Range"), 
      textInput("studentid", "StudentID", value="Enter StudentID:" )
    ),
    mainPanel(DT::dataTableOutput("contents"))
  )
)


server <- function(input,output) { 

  file <- reactive({

    if (input$header) {

      return(fread(input$file1$datapath, 
                   header= TRUE, 
                   sep=",", 
                   quote='"'))

    } else {

      return(fread(input$file1$datapath, 
                   header= FALSE, 
                   sep=",", 
                   quote='"'))
    }

  })

  file_head <- reactive({

    if(input$disp == "head") {

      return(head(file()))

    } else { return(file()) }

  })

  data_filtered <- reactive({

    if (input$dept == "Teacher") {

      return(file_head() %>% mutate_at(.vars = 1, funs(as.Date(strptime(., format = "%Y%m%d")))) %>%
        select_at(.vars = c(1:2, 4)) %>%
        filter_at(.vars = 1, any_vars(. >= input$dates[1] & . <= input$dates[2])))

    }

    else if (input$dept == "Student") {

      return(file_head() %>% mutate_at(.vars = 1, funs(as.Date(strptime(., format = "%Y%m%d")))) %>%
        select_at(.vars = c(1:3)) %>%
        filter_at(.vars = 1, any_vars(. >= input$dates[1] & . <= input$dates[2])))

    }

    else { 

      return(file_head() %>% mutate_at(.vars = 1, funs(as.Date(strptime(., format = "%Y%m%d")))) %>%
        filter_at(.vars = 1, any_vars(. >= input$dates[1] & . <= input$dates[2])))

    }

  })


  output$contents <- DT::renderDataTable({

    if (is.null(input$file1)) {

      return(NULL) } else { return(data_filtered() ) }

  })

}

shinyApp(ui, server)

我看到您还想为Student ID 输入文本。

由于您没有对此指定任何内容,因此我没有将其作为过滤器包含在内(您始终可以使用 Search 过滤 DT 本身),但如果您想继续,上面的示例应该可以帮助您入门朝着那个方向。

【讨论】:

    猜你喜欢
    • 2018-01-26
    • 2021-02-10
    • 2019-11-21
    • 2018-01-18
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    相关资源
    最近更新 更多