Я (очень) новичок в Блестящем и пытаюсь создать приложение, в котором пользователь может ввести свой выбор одного или нескольких параметров, а затем использовать его для запроса к базе данных SQL. Например, если пользователь выбирает «Дублин» или «Абердин», приложение использует RmySQL::dbReadTable()
, чтобы извлечь таблицу с тем же именем из базы данных и вывести ее в таблицу. Если пользователь выбирает «Дублин» и «Абердин», приложение использует DBI::dbGetQuery()
для запроса базы данных, чтобы выбрать определенные столбцы из каждой таблицы, а затем соединить их вместе, выводя результат в таблицу.
Я могу заставить его работать, когда выбран только один вариант, но не более одного.
Отсюда Shiny использует только первый элемент selectInput, когда множественное значение = TRUE Я предполагаю, что могу получить доступ к отдельным элементам input$dataset
, когда выбрано несколько вариантов выбора.
Посмотрев здесь: Получить значение из реактивного контекста в R блестящий на основе пользовательского ввода Я попытался создать запрос, используя реактивную функцию, а затем использовать его во второй реактивной функции, как показано ниже, но приложение не запускается, и я получаю эту ошибку: Ошибка в (функция (классы, fdef, mtable): невозможно найти унаследованный метод для функции 'dbGetQuery' для подписи '' MySQLConnection "," реактивЭкспр "'
library(shiny)
library(rsconnect)
library(RMySQL)
library(dplyr)
library(DBI)
ui = fluidPage(
titlePanel("EWAS database"),
sidebarLayout(
sidebarPanel(
selectInput("dataset", "Choose one or more datasets:",
choices = c("Dublin", "Aberdeen"), selected = NULL, multiple = TRUE),
numericInput("obs", "Number of results to view:", 10),
submitButton("Update View"),
downloadButton("downloadData", "Download")
),
mainPanel(
tableOutput("table")
)
)
)
server <- function(input, output) {
conn <- dbConnect(drv = MySQL(), dbname = "EWAS", host = “xxx”,
username = “xxx”, password = “xxx”)
Dublin <- dbReadTable(conn = conn, name = 'Dublin', value = as.data.frame(Dublin))
Aberdeen <- dbReadTable(conn = conn, name = 'Aberdeen', value = as.data.frame(Aberdeen))
query <- reactive({paste0("'SELECT ",
input$dataset[1], ".", input$dataset[1], "_id, ",
input$dataset[1], ".", input$dataset[1], "_Status_Beta, " ,
input$dataset[1], ".", input$dataset[1], "_Status_SE, " ,
input$dataset[1], ".", input$dataset[1], "_Status_P, " ,
input$dataset[2], ".", input$dataset[2], "_id, " ,
input$dataset[2], ".", input$dataset[2], "_Status_Beta, " ,
input$dataset[2], ".", input$dataset[2], "_Status_SE, " ,
input$dataset[2], ".", input$dataset[2], "_Status_P, " ,
"From ", input$dataset[1], " LEFT JOIN ", input$dataset[2],
" ON ", input$dataset[1], ".", input$dataset[1], "_id ", "= ",
input$dataset[2], ".", input$dataset[2], "_id'")})
custom <- dbGetQuery(conn = conn, query)
datasetInput <- reactive({
if(identical(input$dataset, "Dublin")){
Dublin
} else if (identical(input$dataset, "Aberdeen")){
Aberdeen
} else
custom
})
output$table <- renderTable({
head(datasetInput(), n = input$obs)
})
output$downloadData <- downloadHandler(
filename = function(){
paste(input$dataset, ".csv", sep = "")
},
content = function(file){
write.csv(datasetInput(), file, row.names = F)
}
)
on.exit(dbDisconnect(conn), add = TRUE)
}
shinyApp(ui = ui, server = server)
Я также попытался поместить запрос непосредственно в реактивную функцию (как показано ниже), и в этом случае приложение запускается, но я получаю: внутренняя ошибка в RS_DBI_getConnection: дескриптор поврежденного соединения.
server <- function(input, output) {
conn <- dbConnect(drv = MySQL(), dbname = "EWAS", host = “xxx”,
username = “xxx”, password = “xxx”)
Dublin <- dbReadTable(conn = conn, name = 'Dublin', value = as.data.frame(Dublin))
Aberdeen <- dbReadTable(conn = conn, name = 'Aberdeen', value = as.data.frame(Aberdeen))
datasetInput <- reactive({
if(identical(input$dataset, "Dublin")){
Dublin
} else if (identical(input$dataset, "Aberdeen")){
Aberdeen
} else
dbGetQuery(conn, paste0("'SELECT ",
input$dataset[1], ".", input$dataset[1], "_id, ",
input$dataset[1], ".", input$dataset[1], "_Status_Beta, " ,
input$dataset[1], ".", input$dataset[1], "_Status_SE, " ,
input$dataset[1], ".", input$dataset[1], "_Status_P, " ,
input$dataset[2], ".", input$dataset[2], "_id, " ,
input$dataset[2], ".", input$dataset[2], "_Status_Beta, " ,
input$dataset[2], ".", input$dataset[2], "_Status_SE, " ,
input$dataset[2], ".", input$dataset[2], "_Status_P, " ,
"From ", input$dataset[1], " LEFT JOIN ", input$dataset[2],
" ON ", input$dataset[1], ".", input$dataset[1], "_id ", "= ",
input$dataset[2], ".", input$dataset[2], "_id'"))
})
А также с вариацией ниже ... в соответствии с решением здесь: Как заставить Shiny реактивность работать с SQL базой данных? * 1 021 * но на этот раз приложение не запускается, и я получаю: Ошибка в dbGetQuery (conn = conn, query): объект 'query' не найден.
datasetInput <- reactive({
query <- paste0("'SELECT ",
input$dataset[1], ".", input$dataset[1], "_id, ",
input$dataset[1], ".", input$dataset[1], "_Status_Beta, " ,
input$dataset[1], ".", input$dataset[1], "_Status_SE, " ,
input$dataset[1], ".", input$dataset[1], "_Status_P, " ,
input$dataset[2], ".", input$dataset[2], "_id, " ,
input$dataset[2], ".", input$dataset[2], "_Status_Beta, " ,
input$dataset[2], ".", input$dataset[2], "_Status_SE, " ,
input$dataset[2], ".", input$dataset[2], "_Status_P, " ,
"From ", input$dataset[1], " LEFT JOIN ", input$dataset[2],
" ON ", input$dataset[1], ".", input$dataset[1], "_id ", "= ",
input$dataset[2], ".", input$dataset[2], "_id'")
if(identical(input$dataset, "Dublin")){
Dublin
} else if (identical(input$dataset, "Aberdeen")){
Aberdeen
} else
dbGetQuery(conn, query)
})
Я также думал, что, возможно, смогу получить несколько таблиц по отдельности, затем используйте что-то вроде base::cbind()
их вместе, используя только те столбцы, которые я хочу, но я не могу понять, как мне заставить это работать в этом контексте.
Наконец, я необходимо расширить приложение, включив в него множество других таблиц и, в конечном итоге, у пользователя может быть выбрано до 3 опций с чем-то вроде:
if(length(input$dataset) == 1){
dbReadTable(conn, name = ‘input$dataset’, value = as.data.frame(input$dataset)
} else if (length(input$dataset) == 2){
dbGetQuery(conn, query2)
} else if (length(input$dataset) == 3){
dbGetQuery(conn, query3)
}
, поэтому я действительно надеюсь, что любое решение поможет принять это во внимание. Буду очень признателен за любую помощь или совет!