I am trying to render DataTable output to Shiny. Please find below explanation of my use case:
Connected to my database and got table data to df variable.
sent selected input from select input text box to server script.
Server script should take this input and get the data.
ui.R
library(shiny)
library(RODBC)
library(DBI)
# Establishing connection to ORE environment
dbconnect <- odbcConnect("orecloud", uid="XXXX", pwd="XXXXX", believeNRows=FALSE)
# Preparing data frames to get the data and show in select input pick list
df <- data.frame()
df <- sqlQuery(dbconnect,"SELECT distinct cpan FROM TABLE ")
shinyUI(fluidPage(
headerPanel("ORE XXX Summary"),
sidebarLayout(
sidebarPanel(
helpText("Please select Patient Details.."),
selectInput("CPAN",
label = "Choose patient",
choices = df,
selected = NULL),
submitButton(text = "Submit", icon = NULL)),
mainPanel(
dataTableOutput("tableoutput")
)
)
))
server.R
Server script should take the input and query the data from the table
Render the selected data to UI
If I change value in UI then it should display selected input data.
library(RODBC)
shinyServer(
function(input, output) {
dbconnect <- odbcConnect("orecloud", uid="oracle", pwd="Edvenswa2016", believeNRows=FALSE)
df2 <- data.frame()
input_var <- input$CPAN
print (input_var)
my_query <- paste("select * from CYTOKINE where CPAN= ", input_var)
print(myquery)
df2 <- sqlQuery(dbconnect,myquery)
output$tableoutput <- renderDataTable({df2})
}
)
You need to do it reactive
df2=reactive({
input_var <- input$CPAN
my_query <- paste("select * from CYTOKINE where CPAN= ", input_var)
sqlQuery(dbconnect,myquery)
})
and use like renderDataTable({df2()}) } )
If input$CPAN is character you need paste0("select * from CYTOKINE where CPAN= '", input_var,"'")
Also dont forget disconect
session$onSessionEnded(function() {
odbcClose(dbconnect )
})
Related
I tried to read dataframe rows from one column to feel a list in a SelectInput objet in a UI.R Shiny
I have a problem with global or local ref between the UI and Server and I don't know if the format is right to import items in the selectInput List
Here my DF Ref_comp with just one column (STEP_NAME):
! STEP_NAME !
-----------------
L1_2_3_LR
C46-C77-OTHERS
R4
R10
C56
Q4
L4
Here my UI.R
shinyUI(pageWithSidebar(
headerPanel("My header Text"),
sidebarPanel(
radioButtons("test", "Select a DataBase",
c("test1"="test1",
"test2"="test2")),
textInput("card", "Enter the code card", "CARD.EX"),
textInput("comp", "Enter the ref comp", "R3"),
######## Here what I tried to do ########
selectInput("comp_sel","Component", choices=
as.character(unique(unlist(Ref_comp$STEP_NAME)))),
##########################################
downloadButton("plot_export", "Save PDF")
),
mainPanel(
#h4("Text2"),
library(plotly),
plotlyOutput("plot"))
))
Here my Server.R
shinyServer(function(input,output){
output$plot <- renderPlotly({
con <- odbcConnect(con, uid="xxx")
##### Here the SQL Query to have my items ######################
sql_ref = paste("select DISTINCT ...") # My SQL query on distant server
###### Output in DF Ref_comp ##############
Ref_comp <- sqlQuery(db, paste (sql_ref))
##########################################
odbcClose(data_testeur)
#### An other SQL Query for the graph #######
graph <- ggplot(...
ggplotly(graph) # Print graph
}
)
})
Thank you for your help
Your problem is that you the data_frame Ref_comp is generated in server.r when this is the case we have to generate the selectInput dynamic with a renderUI and uiOutput() like this:
shinyUI(pageWithSidebar(
headerPanel("My header Text"),
sidebarPanel(
radioButtons("test", "Select a DataBase",
c("test1"="test1",
"test2"="test2")),
textInput("card", "Enter the code card", "CARD.EX"),
textInput("comp", "Enter the ref comp", "R3"),
######## Here what I tried to do ########
uiOutput("selectComp"),
##########################################
downloadButton("plot_export", "Save PDF")
),
mainPanel(
#h4("Text2"),
library(plotly),
plotlyOutput("plot"))
))
and server
shinyServer(function(input,output){
refDataFrame <- reactive({
con <- odbcConnect(con, uid="xxx")
##### Here the SQL Query to have my items ######################
sql_ref = paste("select DISTINCT ...") # My SQL query on distant server
###### Output in DF Ref_comp ##############
Ref_comp <- sqlQuery(db, sql_ref)
odbcClose(data_testeur)
Ref_comp
})
output$selectComp <- renderUI(
selectInput("comp_sel","Component", choices=
as.character(unique(unlist(refDataFrame()[["STEP_NAME"]]))))
)
output$plot <- renderPlotly({
Ref_comp <- refDataFrame()
#### An other SQL Query for the graph #######
graph <- ggplot(...)
ggplotly(graph) # Print graph
}
)
})
Since we now need the result of the database query in two places have put it in a separate reactive function
I am not able to give reference of column name from dbgetquery to the option choices specifying the column name from the query in updateselectizeinput in shiny. Can anyone help?
Example code:
query= reactive({ con, 'select * from database' })
updateselectizeinput(session, 'inputid', choice="how to give reference from query here", server=TRUE)
Actually it is very hard to understand what exactly do You mean, but i will just assume that You want to use the column names from the database table as a choice in selectizeInput. For this purpose You do not need updateSelectizeInput.
Here is the sample code with additional comments in it:
library(shiny)
u <- shinyUI(fluidPage(
titlePanel("Mutually Dependent Input"),
sidebarLayout(
sidebarPanel(
uiOutput("select1")),
mainPanel()
)
))
s <- shinyServer(function(input, output,session) {
queryOutput <- reactive({
data <- dbGetQuery(con, 'select * from database')}) # Here is Your SQL Query which gives You the table
output$select1 <- renderUI({
selectizeInput("select1_ui", "Select column name", choices = names(queryOutput())) # Here is Your selectizeInput with choices as column names
})
})
shinyApp(u,s)
As the title says, I'm trying to get Shiny to display a SelectBox so I can dynamically select records from a SQL Server Table, and based on the selection of the CATEGORY, display everything in the table. The script below must be close. I am getting the SelectBox to work, but when I make a selection, nothing is displayed.
library(shiny)
library(RODBCext)
shinyApp(
ui =
shinyUI(
fluidPage(
uiOutput("select_category"),
tableOutput("display_data")
# plotOutput("plot_data")
)
),
server = shinyServer(function(input, output, session){
# A reactive object to get the query. This lets you use
# the data in multiple locations (plots, tables, etc) without
# having to perform the query in each output slot.
QueriedData <-
reactive({
req(input$showDrop)
ch <- odbcDriverConnect('driver={SQL Server};server=MyServer;database=Northwind;trusted_connection=true')
showList <- sqlExecute(ch,
"SELECT * FROM [NORTHWND].[dbo].[Customers] WHERE [CUSTOMERID] = ?",
data = list(AnalyteId = input$showDrop),
fetch = TRUE,
stringsAsFactors = FALSE)
odbcClose(ch)
showList
})
# The select input control. These can be managed dynamically
# from the server, and then the control send back to the UI
# using `renderUI`
output$select_category <-
renderUI({
ch <- odbcDriverConnect('driver={SQL Server};server=MyServer;database=Northwind;trusted_connection=true')
showList <- sqlExecute(ch,
"SELECT DISTINCT AnalyteId From [NORTHWND].[dbo].[Customers] ORDER BY [CUSTOMERID]",
fetch = TRUE,
stringsAsFactors = FALSE)
odbcClose(ch)
selectInput(inputId = "showDrop",
label = "Select Asset",
showList$AnalyteId)
})
# Display the data in a table
output$display_data <-
renderTable({
QueriedData()
})
# Display a plot
# output$plot_data <-
# renderPlot({
# plot(QueriedData()) # fill in the plot code you want to use.
# })
})
)
How can I get this working? Also, can you make the table dynamically selectable, or is that not an option?
It seems like you're missing some components. Some notes:
Your UI definition is invalid. Each argument to the UI should produce some kind of UI element. The lines where you define your connection and export the data from SQL Server will won't behave the way you are expecting them to here. You should either do these actions on the server, or you should define them globally.
You are retrieving data into your output$cumReturn slot, but you are using a renderPlot call to do it. This is somewhat disjoint. If you wish to render a plot, you should generate a plot. If you wish to show data, you should use renderTable (or something similar).
You also haven't displayed the cumReturn output slot anywhere in the UI, so the query is never actually being called.
Lastly, your query in output$cumReturn will fail when it goes to the server. I am guessing you mean to use input$showDrop in a WHERE statement, but your query has no such statement. This is not casting an error in the code above because you never try to render the cumReturn output, so the query is never being called.
Here's a variation on your code that should produce a table of data that fall within the category.
library(shiny)
library(RODBCext)
shinyApp(
ui =
shinyUI(
fluidPage(
uiOutput("select_category"),
tableOutput("display_data"),
plotOutput("plot_data")
)
),
server = shinyServer(function(input, output, session){
# A reactive object to get the query. This lets you use
# the data in multiple locations (plots, tables, etc) without
# having to perform the query in each output slot.
QueriedData <-
reactive({
req(input$showDrop)
ch <- odbcDriverConnect('...')
showList <- sqlExecute(ch,
"SELECT * FROM dbo.Analyte WHERE AnalyteId = ?",
data = list(AnalyteId = input$showDrop),
fetch = TRUE,
stringsAsFactors = FALSE)
odbcClose(ch)
showList
})
# The select input control. These can be managed dynamically
# from the server, and then the control send back to the UI
# using `renderUI`
output$select_category <-
renderUI({
ch <- odbcDriverConnect('...')
showList <- sqlExecute(ch,
"SELECT DISTINCT AnalyteId FROM dbo.Analyte ORDER BY AnalyteId",
fetch = TRUE,
stringsAsFactors = FALSE)
odbcClose(ch)
selectInput(inputId = "showDrop",
label = "Select Asset",
showList$AnalyteId)
})
# Display the data in a table
output$display_data <-
renderTable({
QueriedData()
})
# Display a plot
output$plot_data <-
renderPlot({
plot(QueriedData()) # fill in the plot code you want to use.
})
})
)
library(shiny)
library(RODBCext)
shinyApp(
ui =
shinyUI(
fluidPage(
uiOutput("select_category"),
tableOutput("display_data")
# plotOutput("plot_data")
)
),
# server needs the function; looks ok
server = shinyServer(function(input, output, session)
{
# A reactive object to get the query. This lets you use
# the data in multiple locations (plots, tables, etc) without
# having to perform the query in each output slot.
QueriedData <- reactive({
req(input$showDrop)
ch <- odbcDriverConnect("driver={SQL Server};server=SERVER;database=DB;trusted_connection=true")
showList <- sqlExecute(ch, "SELECT * FROM [DB].[dbo].[TABLE] WHERE Category = ?",
data = list(Category = input$showDrop),
fetch = TRUE,
stringsAsFactors = FALSE)
odbcClose(ch)
showList
})
# The select input control. These can be managed dynamically
# from the server, and then the control send back to the UI
# using `renderUI`
output$select_category <- renderUI({
ch <- odbcDriverConnect("driver={SQL Server};server=SERVER;database=DB;trusted_connection=true")
showList <- sqlExecute(ch, "Select Distinct Category From [DB].[dbo].[TABLE] Order by Category",
fetch = TRUE,
stringsAsFactors = FALSE)
odbcClose(ch)
selectInput(inputId = "showDrop",
label = "Select Asset",
showList$Category)
})
# Display the data in a table
output$display_data <- renderTable({
QueriedData()
})
# Display a plot
# output$plot_data <-
# renderPlot({
# plot(QueriedData()) # fill in the plot code you want to use.
# })
})
)
I'm building a shiny app that queries an SQL database so the user can ggplot the data. I would like the user to be able to rename factors manually but am struggling to get going. Here is an example of what I want to do:
ui.R
library(markdown)
shinyUI(fluidPage(
titlePanel("Reactive factor label"),
sidebarLayout(
sidebarPanel(
numericInput("wafer", label = h3("Input wafer ID:"), value = NULL),
actionButton("do", "Search wafer"),
textInput("text", label = h3("Factor name to change"), value = ""),
textInput("text", label = h3("New factor name"), value = ""),
actionButton("do2", "Change name")
),
mainPanel(
verbatimTextOutput("waf"),
verbatimTextOutput("que"),
verbatimTextOutput("pos"),
dataTableOutput(outputId="tstat")
)
)
)
)
server.R
# Create example data
Name <- factor(c("Happy", "New", "Year"))
Id <- 1:3
dd <- data.frame(Id, Name)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
dbWriteTable(con, "dd", dd)
query <- function(...) dbGetQuery(con, ...)
wq = data.frame()
sq = data.frame()
shinyServer(function(input, output){
# create data frame to store reactive data set from query
values <- reactiveValues()
values$df <- data.frame()
# Wait for user to search
d <- eventReactive(input$do, { input$wafer })
# Reactive SQL query
a <- reactive({ paste0("Select * from dd where Id=",d()) })
wq <- reactive({ query( a() ) })
# Check outputs
output$waf <- renderPrint(input$wafer)
output$que <- renderPrint({ a() })
output$pos <- renderPrint( wq()[1,1] )
# observe d() so that data is not added until user presses action button
observe({
if (!is.null(d())) {
sq <- reactive({ query( a() ) })
# add query to reactive data frame
values$df <- rbind(isolate(values$df), sq())
}
})
output$tstat <- renderDataTable({
data <- values$df
})
})
In static R I would normally use data table to rename factors i.e.:
DT <- data.table(df)
DT[Name=="Happy", Name:="Sad"]
But I'm not sure how to go about this with a reactiveValues i.e. values$df.
I have read this (R shiny: How to get an reactive data frame updated each time pressing an actionButton without creating a new reactive data frame?). This lead me to try this but it doesn't do anything (even no error):
observeEvent(input$do2, {
DT <- data.table(values$df)
DT[Name == input$text1, Name := input$text2]
values$df <- data.frame(values$df)
})
Perhaps there is a way around this..maybe there is a way to use an action button to "lock in" the data as a new data frame, which can then be used to rename?
Sorry for such a long winded question. My real app is much longer and more complex. I have tried to strip it down.
Your approach works but there are a few issues in your app.
In ui.R, both textInput have the same id, they need to be different so you can refer to them in the server.R. In the observeEvent you posted, you refer to input$text1 and input$text2 so you should change the id of the textInputs to text1 and text2.
In the observeEvent you posted, the last line should be values$df <- as.data.frame(DT), otherwise it does not change anything.
How do you use values obtained from a renderUI element in a reactive wrapper?
i.e. My code:
CompanyNames <- sqlQuery(connection, "SELECT Companynm FROM RiskMgm_Company")
output$CompNameSelector <- renderUI({
selectInput("compName","Company Name:",as.vector(CompanyNames[,1]))
})
CompID <- reactive({
CompID <<- sqlQuery(paste("SELECT CompanyID FROM RiskMgm_Company WHERE Companynm = '",compName,"'"))
})
output$MotorSelector <- renderUI({
selectInput("MachSer","Machine:",sqlQuery(connection,paste("SELECT Motor_func FROM RiskMgm_Motor WHERE Company_ID='",CompID,"'")))
})
My error:
Successfilly opened connection to db
Error in paste("SELECT CompanyID FROM RiskMgm_Company WHERE Companynm = '", :
could not find function "compName"
What am I doing wrong? Essentially what I want is a list of companies given by the SQL query. Then depending on the Company selected it will show the motors that belong to that company in the next dropdown box
Thanks
You would refer to the elements by their id for example input$compName. As a contrived example here
is a simple shiny app with two selectInput's. The second selectInput choices depend on the value of the first. Referencing the output of widgets created by renderUI is no different from referencing the same widgets if they had been in UI.R from the beginning:
library(shiny)
myDF <- data.frame(A = 1:4, B = 3:6, C = 6:9, D = 10:13)
runApp(
list(
ui = fluidPage(
uiOutput("myList"),
uiOutput("myNumbers")
)
, server = function(input, output, session){
output$myList <- renderUI({
selectInput("compName", "Company Name:", LETTERS[1:4])
})
output$myNumbers <- renderUI({
selectInput("compNo", "Product Line:", myDF[, input$compName])
})
}
)
)