我正在尝试创建一个闪亮的应用程序,用户可以在其中上载.csv文件,然后对该数据框应用过滤器,然后使用ggplot2进行绘制。不幸的是,当我试图从应该上传的.csv变量创建一个选择输入菜单时,偶然发现了一个问题。
要创建一个简单的示例,我们可以将diamonds
中的ggplot2
数据集导出为.csv文件:
write.csv(diamonds, "diamonds.csv")
然后创建闪亮的应用程序:
library(shiny)
library(shinyWidgets)
library(ggplot2)
ui <- fluidPage(
titlePanel("test shiny"),
# Sidebar with a slider input for number of bins
sidebarLayout(sidebarPanel(
fileInput('file1', 'Choose file to upload',
accept = c(
'text/csv',
'text/comma-separated-values',
'text/tab-separated-values',
'text/plain',
'.csv',
'.tsv'
)
),
tags$hr(),
pickerInput(
inputId = "caratx",
label = "Choose carat",
choices = c("Select all", unique(user_data$carat)),
multiple = TRUE
),
selectInput(
inputId = "clarityx",
label = "Choose distance: ",
choices = unique(user_data$clarity)
)
),
mainPanel(plotOutput("endplot"))
))
# Define server logic
server <- function(input, output) {
output$endplot <- renderPlot({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
user_data <- read.csv(inFile$datapath, header = T,
sep = ",", quote = input$quote)
validate(
need(input$entityx, 'Please select at least one carat'),
need(input$indicatorx, 'Please select at least one clarity')
)
if (input$caratx %in% "Select all") {
user_data <- user_data %>%
filter(carat %in% input$caratx)
} else {
user_data <- user_data %>%
filter(carat %in% input$caratx) %>%
filter(clarity %in% input$clarityx)
}
user_data %>%
ggplot(aes(x = `cut`)) +
geom_point(aes(y = price), color = "red") +
geom_point(aes(y = depth), color = "blue")
})
}
# Run the application
shinyApp(ui = ui, server = server)
这是输出:
Error in unique(user_data$carat) : object 'user_data' not found
有没有办法使这项工作成功?
非常感谢!
答案 0 :(得分:3)
您要解决的实际问题应通过将user_data
变成反应式并使用uiOutput + renderUI呈现输入来解决,如@kwiscion正确注释。
但是不幸的是,您的代码还有其他一些错误,使其无法再现:
diamonds
,而不是cars
input$quote
在您的代码中不存在,因此我删除了对其的引用library(dplyr)
input$entityx
和input$indicatorx
不存在以上4个错误与您的问题无关,但使回答问题变得越来越困难。将来,请尝试确保您发布的代码正确且可重复。
下面是您的问题的答案,它解决了上面的4个问题,并实现了@kwiscion的两个建议
library(shiny)
library(shinyWidgets)
library(ggplot2)
library(dplyr)
ui <- fluidPage(
titlePanel("test shiny"),
# Sidebar with a slider input for number of bins
sidebarLayout(sidebarPanel(
fileInput('file1', 'Choose file to upload',
accept = c(
'text/csv',
'text/comma-separated-values',
'text/tab-separated-values',
'text/plain',
'.csv',
'.tsv'
)
),
tags$hr(),
uiOutput("caratx_input"),
uiOutput("clarityx_input")
),
mainPanel(plotOutput("endplot"))
))
# Define server logic
server <- function(input, output) {
file_data <- reactive({
req(input$file1)
read.csv(input$file1$datapath, header = TRUE,
sep = ",")
})
output$caratx_input <- renderUI({
req(file_data())
pickerInput(
inputId = "caratx",
label = "Choose carat",
choices = c("Select all", unique(file_data()$carat)),
multiple = TRUE
)
})
output$clarityx_input <- renderUI({
req(file_data())
selectInput(
inputId = "clarityx",
label = "Choose distance: ",
choices = unique(file_data()$clarity)
)
})
output$endplot <- renderPlot({
req(file_data())
validate(
need(input$caratx, 'Please select at least one carat'),
need(input$clarityx, 'Please select at least one clarity')
)
user_data <- file_data()
if (input$caratx %in% "Select all") {
user_data <- user_data %>%
filter(carat %in% input$caratx)
} else {
user_data <- user_data %>%
filter(carat %in% input$caratx) %>%
filter(clarity %in% input$clarityx)
}
user_data %>%
ggplot(aes(x = `cut`)) +
geom_point(aes(y = price), color = "red") +
geom_point(aes(y = depth), color = "blue")
})
}
# Run the application
shinyApp(ui = ui, server = server)
答案 1 :(得分:1)
您需要
pickerInput
(https://shiny.rstudio.com/articles/dynamic-ui.html)渲染renderUI
。(下面是完整代码)
user_data
)时,必须通过将计算放入reactive({ })
中来使其成为反应式。然后,您可以引用类似于函数的值,即user_data()
。因此,您的情况应该是:user_data <- reactive({
read.csv(input$file1$datapath, header = T,
sep = ",", quote = input$quote)
})
user_data() %>% ...
此外,还必须将其从renderPlot()
中拉出才能起反应性作用。
renderUI()
在服务器端呈现输入:ui.R
...
uiOutput('caratxui'),
...
server.R
...
output$caratxui <- renderUI({
pickerInput(
inputId = "caratx",
label = "Choose carat",
choices = c("Select all", unique(user_data()$carat)),
multiple = TRUE
)
})
...
完整代码:
library(shiny)
library(shinyWidgets)
library(ggplot2)
ui <- fluidPage(
titlePanel("test shiny"),
# Sidebar with a slider input for number of bins
sidebarLayout(sidebarPanel(
fileInput('file1', 'Choose file to upload',
accept = c(
'text/csv',
'text/comma-separated-values',
'text/tab-separated-values',
'text/plain',
'.csv',
'.tsv'
)
),
tags$hr(),
uiOutput('caratxui'),
selectInput(
inputId = "clarityx",
label = "Choose distance: ",
choices = unique(user_data$clarity)
)
),
mainPanel(plotOutput("endplot"))
))
# Define server logic
server <- function(input, output) {
user_data <- reactive({
read.csv(input$file1$datapath, header = T,
sep = ",", quote = input$quote)
})
output$caratxui <- renderUI({
pickerInput(
inputId = "caratx",
label = "Choose carat",
choices = c("Select all", unique(user_data()$carat)),
multiple = TRUE
)
})
output$endplot <- renderPlot({
validate(
need(input$entityx, 'Please select at least one carat'),
need(input$indicatorx, 'Please select at least one clarity')
)
user_data() %>%
filter(carat %in% input$caratx) %>%
filter(clarity %in% input$clarityx |
input$caratx == "Select all") %>%
ggplot(aes(x = `cut`)) +
geom_point(aes(y = price), color = "red") +
geom_point(aes(y = depth), color = "blue")
})
}
# Run the application
shinyApp(ui = ui, server = server)