R shiny ERROR:'closure'类型的对象不是子集

dig*_*git 3 r shiny

我使用以下代码,我总是得到这个子表函数错误.我的子集是什么,我错在哪里.这应该是我修改过的一些基本的入口代码,它在某些时候起作用,我看不到错误.

谢谢

server.R

library(shiny)

# Define a server for the Shiny app
shinyServer(function(input, output) {

  # Filter data based on selections
  output$table <- renderDataTable({
    data <- read.table("my.csv", sep =',', header =TRUE)
    if (input$shortdesc != "All"){
      data <- data[data$ShortDescription == input$shortdesc,]
    }
    if (input$taken != "All"){
      data <- data[data$Taken == input$taken,]
    }
    if (input$location != "All"){
      data <- data[data$Location == input$location,]
    }
    data
  })

})
Run Code Online (Sandbox Code Playgroud)

ui.R

library(shiny)
# Define the overall UI

shinyUI(
  fluidPage(
    titlePanel("My Items"),

    # Create a new Row in the UI for selectInputs
    fluidRow(
      column(4, 
             selectInput("man", 
                         "What:", 
                         c("All", 
                           unique(as.character(data$ShortDescription))))
      ),
      column(4, 
             selectInput("trans", 
                         "Where:", 
                         c("All", 
                           unique(as.character(data$Location))))
      ),
      column(4, 
             selectInput("cyl", 
                         "Who:", 
                         c("All", 
                           unique(as.character(data$Taken))))
      )        
    ),
    # Create a new row for the table.
    fluidRow(
      dataTableOutput(outputId="table")
    )    
  )  
)
Run Code Online (Sandbox Code Playgroud)

更新:

为什么示例(见下文)有效,而我将其更改为my.csv的那一刻它会破坏?如果"data"是buildin函数,那么下面的例子也不会发生冲突吗?抱歉不理解,但这让我很困惑.

server.R

library(shiny)

# Load the ggplot2 package which provides
# the 'mpg' dataset.
library(ggplot2)

# Define a server for the Shiny app
shinyServer(function(input, output) {

  # Filter data based on selections
  output$table <- renderDataTable({
    data <- mpg
    if (input$man != "All"){
      data <- data[data$manufacturer == input$man,]
    }
    if (input$cyl != "All"){
      data <- data[data$cyl == input$cyl,]
    }
    if (input$trans != "All"){
      data <- data[data$trans == input$trans,]
    }
    data
  })

})
Run Code Online (Sandbox Code Playgroud)

ui.R.

library(shiny)

# Load the ggplot2 package which provides
# the 'mpg' dataset.
library(ggplot2)

# Define the overall UI
shinyUI(
  fluidPage(
    titlePanel("Basic DataTable"),

    # Create a new Row in the UI for selectInputs
    fluidRow(
      column(4, 
          selectInput("man", 
                      "Manufacturer:", 
                      c("All", 
                        unique(as.character(mpg$manufacturer))))
      ),
      column(4, 
          selectInput("trans", 
                      "Transmission:", 
                      c("All", 
                        unique(as.character(mpg$trans))))
      ),
      column(4, 
          selectInput("cyl", 
                      "Cylinders:", 
                      c("All", 
                        unique(as.character(mpg$cyl))))
      )        
    ),
    # Create a new row for the table.
    fluidRow(
      dataTableOutput(outputId="table")
    )    
  )  
)
Run Code Online (Sandbox Code Playgroud)

Liv*_*ius 12

扩展@Roland的评论:你发生了命名空间冲突.data基数R中有一个函数,因此如果R data在当前环境中找不到对象,则该函数data将从全局环境中引用.在您的特定情况下,这发生是因为ui.R并且server.R处于不同的环境中,而且,各个功能体都具有自己的环境.所以datain fluidRow(...)中没有引用datafrom output$table.您需要传递参数和/或使用其功能动态构建UI.例如,请参见此处.

更新更新的问题:

替换datampgin ui.R修复了问题,因为它mpg被定义为全局环境中的数据集(这是副作用library(ggplot2)).所以mpg(几乎)总是可以访问并具有必要的属性.对于一个更加公平的比较,替换mpgui.Rdata,这应该带回的老问题,是因为data在全球环境指的是功能,而不是你想操纵数据帧.

超级更新,提供更通用的解决方案,用于动态定义和加载每个数据集的选择元素:

服务器代码循环遍历所选数据框的所有列,并为每个类型不同于double的列动态生成选择框.(与双打的唯一性和相等性只是要求麻烦.)这避免了范围问题,因为UI元素是在server.R调用加载数据的反应函数之后创建的.

server.R

library(shiny)
library(ggplot2)
# Define a server for the Shiny app
shinyServer(function(input, output) {

  get.data <- reactive({
    switch(input$dataset,
           "rock" = rock,
           "pressure" = pressure,
           "cars" = cars,
           "mpg" = mpg,
           "mtcars" = mtcars,
           "diamonds" = diamonds)
  })

  # Filter my.data based on selections
  output$table <- renderDataTable({
    my.data <- get.data()
    for(n in names(my.data)){
        # avoid too many cases ... 
        # unique() with double is just asking for trouble
        if(typeof(my.data[,n]) != "double"){ 
            val <- eval(parse(text=paste0("input$",n)))
            print(val)
            if(val != "All"){
                my.data <- eval(parse(text=paste0("subset(my.data,",n,"==",val,")")))
            }
        }
    }
    my.data
  })

  output$dyn.ui <- renderUI({
      my.data <- get.data()
      sel <- NULL
      for(n in names(my.data)){
          # avoid too many cases ... 
          # unique() with double is just asking for trouble
          if(typeof(my.data[,n]) != "double"){ 
              sel <- c(sel,
                   selectInput(n, n, choices=c("All",unique(my.data[,n])))
                   )
          }
      }
      sel
  })

})
Run Code Online (Sandbox Code Playgroud)

ui.R

library(shiny)

# Define the overall UI

shinyUI(fluidPage(
    titlePanel("Displaying tables dynamically with renderUI() and eval()"),

    sidebarLayout(
        sidebarPanel(h2("Selection"),
                     selectInput("dataset", "Dataset", c("rock", "pressure", "cars","mtcars","diamonds")),
                     # Create a new Row in the UI for selectInputs
                     uiOutput("dyn.ui")

        )
        ,mainPanel(h2("Data"),
           dataTableOutput(outputId="table")       
        )
    )


))
Run Code Online (Sandbox Code Playgroud)