For Loop in RShiny: Warning: "Error in names: 0 arguments passed to ... which requires 1" - mysql

using RShiny/SQL for the first time so I'm sure I'm misunderstanding a fundament but none of the documentation is helping. I'm trying to:
(1) let the user choose which SQL table to load in
(2) submit a string of characters (protein names)
(3) return which protein names are in the chosen table
I've managed the first 2 fine but on the for loop I get '0 arguments passed to 'names' which requires one' and I'm not sure why. My code:
UI:
>library(shiny)
ui <- fluidPage(
titlePanel("TBD"),
sidebarLayout(
sidebarPanel(
selectInput("variable", "variable:",
list("Knoener" = "Knoener",
"Liz" = "Liz",
"Kula" = "Kula")),
actionButton("button1", "Click Me"),
textInput("names","Enter protein symbols"),
actionButton("button2", "Click Me"),
actionButton("button3", "Let's go!")
),
mainPanel(
textOutput("text1"),
textOutput("text2"),
textOutput("text3")
)
))
SERVER:
library("shiny")
library("DBI")
library("dplyr")
library("dbplyr")
library('pool')
loadData <- function(table) {
db <- dbConnect(MySQL(), dbname = "knoenerdb", host = "localhost",
user = "root",
password = "blahblah")
query <- sprintf("SELECT * FROM %s", table)
chosendata <- dbGetQuery(db, query)
dbDisconnect(db)
}
server <- function(input, output) {
chosendata <- observeEvent(input$button1, {
loadData(input$variable)
output$text1 <- renderText({paste("input is",input$variable)})})
names <- observeEvent( input$button2, {
names <- unlist(strsplit(input$names, ", "))
output$text2 <- renderText({paste("names are",names)})
})
observeEvent( input$button3, {
for(i in 1:length(names())){
if(names()[i] %in% chosendata()$proteins){
updated = c(updated,names()[i])
} else
updated = c(updated, "NULL")
}
output$text3 <- renderText({paste("matches are",updated)})
})
}
Thanks for the help!

My guess would be that you have some names clashing. Consider renaming text input names to something unique.
> names()
Error in names() : 0 arguments passed to 'names' which requires 1

Related

How define Server for Copy/Paste regions as input in R/Shiny?

I have a shiny which can be used to overlap between query regions and a given data table (e.g. DF). I put two options for uploading query data 1) as .bed format and 2) inserting data as copy/paste.
The shiny works well with uploading .bed file but I am not sure how can I define Server for copy/paste (text) data.
Thank you in advance for any suggestion!
DF<- data.table(chr=c("chr1","chr2"),start=c(10,20),end=c(20,30))%>% setkey(chr, start, end)
text<- data.table(chr=c("chr1","chr2"),start=c(15,25),end=c(15,30))%>% setkey(chr, start, end)
ui <- fluidPage(
sidebarLayout(
sidebarPanel (
p(strong ("Find overlap between query file and data"),style = "color:blue;"),
br(),
selectInput("choose","Choose file source",choices = c("file","text"),selected = "file"),
conditionalPanel("input.choose=='file'",
fileInput("query.file", "Upload genomic coordinates in .bed
format:",multiple = F,accept = ".bed")),
conditionalPanel("input.choose=='text'",
textAreaInput("query.text", "Enter genomic coordinates:")),
actionButton("run", "run"),
width = "2"),
mainPanel(
dataTableOutput("DFtable"),
dataTableOutput("overlap_table"))
)
)
server <- function (input, output, session) {
## Read user .bed file
user_query.file <- reactive({
req(input$query.file)
ext <- tools::file_ext(input$query.file$name)
switch(ext,
bed = fread(input$query.file$datapath,header=F)%>%
dplyr::rename (chr =V1, start=V2, end=V3) %>% setkey(chr, start, end)%>% unique()
)
})
## overlapping between query file and table
overlap <- eventReactive(input$run, {
req(input$run)
withProgress(message = 'Analysis in progress', value = 0, {
query.overlap<- foverlaps(user_query.file() ,DF, nomatch = 0) %>%
unique()
})
})
## output
output$DFtable<- renderDataTable({ DF })
output$overlap_table <- renderDT({overlap () })
}
shinyApp(ui, server)
Desire out put using TEXT input option:
chr start end i.start i.end
chr1 15 15 10 20
chr2 25 30 20 30
Not sure on how your copied text looks like, but assuming something like:
chr,start,end
chr1,10,20
chr4,34,56
All you need is to parse the text contents of the UI input and assigned it to DF variable. Your run event handler could look like:
## overlapping between query file and table
overlap <- eventReactive(input$run, {
req(input$run)
#Requiring text input and parsing it
req(input$query.text)
DF <- data.table(read.csv(text=input$query.text)) %>% setkey(chr, start, end)
withProgress(message = 'Analysis in progress', value = 0, {
query.overlap<- foverlaps(text ,DF, nomatch = 0) %>%
unique()
})
})
Then when clicking on the run button, the analysis is executed and the overlap reactive value is updated. If the comparison is always between file and text provided, you should also include a req(user_query.file()) to ensure the file has been provided and correctly parsed.

How do I get output value in server based on selected input value in ui?

I am trying to create a shiny app that works like a look up table -- I am using multiple columns from my data frame as input variables in the sidebar and based on the inputs the user selects from the dropdown, I am trying to get a corresponding output for two variables (one numeric and one character) which exist in the same table.
However, when I try to link my input to get the matching output in the server code, I get the following error for my numeric output variable: "Warning: Error in writeImpl: Text to be written must be a length-one character vector" and the following error for my character output variable: "operations are possible only for numeric, logical or complex types".
I need help in resolving this, thank you! I have attached my simplified code and data with two input and two output variables for reference.
This is my data:
"input1","input2","NumericOutput","CharacterOutput"
"precarious","precarious",0,"precarious"
"precarious","precarious",2.950337429,"precarious"
"precarious","precarious",4.827824883,"precarious"
"precarious","precarious",8.314587299,"precarious"
"precarious","precarious",7.276345388,"precarious"
"precarious","precarious",10.22668282,"precarious"
"precarious","precarious",12.10417027,"precarious"
"precarious","precarious",15.59093269,"precarious"
"precarious","precarious",0.622945146,"precarious"
"precarious","precarious",3.573282575,"precarious"
"precarious","precarious",5.450770029,"precarious"
"precarious","precarious",8.937532445,"precarious"
"precarious","precarious",7.899290535,"precarious"
"precarious","precarious",10.84962796,"precarious"
"precarious","precarious",12.72711542,"precarious"
"precarious","precarious",16.21387783,"precarious"
"precarious","precarious",3.737670877,"precarious"
"precarious","moderate",6.688008306,"precarious"
"good","precarious",8.565495761,"precarious"
This is my code:
## loading packages
{
library(shiny)
library(shinydashboard)
library(htmltools)
library(rvest)
library(XML)
library(measurements)
library(ggplot2)
library(ggrepel)
library(plotly)
library(shinyjs)
library(shinyWidgets)
}
Test <- read.csv("Test.csv", stringsAsFactors = FALSE)
summary(Test)
lapply(Test,class)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
useShinyjs(),
selectInput ("a",label = colnames(Test[1]),
choices = (Test[[1]])),
selectInput("b",colnames(Test[2]),
choices = Test[[2]])
),
dashboardBody(
fluidRow(valueBoxOutput("info_box1", width = 6)),
fluidRow(valueBoxOutput("info_box2", width = 6))
)
)
server <- function(input, output) {
output$info_box1 <- renderValueBox({
valueBox(value = paste0("Score in %: ",
Test$NumericOutput[Test$input1 == input$a]
& Test$NumericOutput[Test$input2 == input$b]),
subtitle = NULL) })
output$info_box2 <- renderValueBox({
valueBox(value = paste0("Assessment: ",(Test$CharacterOutput[Test$input1 == input$a])&
(Test$CharacterOutput[Test$input2 == input$b])),
subtitle = NULL)
})
}
shinyApp(ui, server)
Welcome to stackoverflow! The problem with the above code is, that the choices you are providing to populate the selectInput's aren't identifying a single row of your data.frame. However, valueBox's value-argument expects a single string.
I'm not sure what your expected result is, but maybe the following helps to understand what the issue is:
## loading packages
{
library(shiny)
library(shinydashboard)
library(shinyjs)
}
Test <- data.frame(
stringsAsFactors = FALSE,
input1 = c("precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","precarious","good"),
input2 = c("precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","moderate",
"precarious"),
NumericOutput = c(0,2.950337429,4.827824883,
8.314587299,7.276345388,10.22668282,12.10417027,
15.59093269,0.622945146,3.573282575,5.450770029,8.937532445,
7.899290535,10.84962796,12.72711542,16.21387783,
3.737670877,6.688008306,8.565495761),
CharacterOutput = c("precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious","precarious","precarious","precarious",
"precarious")
)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
useShinyjs(),
selectInput("a", label = colnames(Test[1]),
choices = unique(Test[[1]])),
selectInput("b", colnames(Test[2]),
choices = unique(Test[[2]]))
),
dashboardBody(fluidRow(valueBoxOutput("info_box1", width = 6)),
fluidRow(valueBoxOutput("info_box2", width = 6)))
)
server <- function(input, output) {
output$info_box1 <- renderValueBox({
valueBox(
value = paste0("Score in %: ",
Test$NumericOutput[Test$input1 == input$a],
Test$NumericOutput[Test$input2 == input$b], collapse = ", "),
subtitle = NULL)
})
output$info_box2 <- renderValueBox({
valueBox(value = paste0(
"Assessment: ",
Test$CharacterOutput[Test$input1 == input$a],
Test$CharacterOutput[Test$input2 == input$b], collapse = ", "),
subtitle = NULL)
})
}
shinyApp(ui, server)
I basically needed an output value for both my output variables by checking all conditions and not just fulfilling any one condition.
Instead of using Test$NumericOutput[Test$input1 == input$a]
& Test$NumericOutput[Test$input2 == input$b]
I used Test$NumericOutput[Test$input1 == input$a & Test$input2 == input$b] and it worked.

Shiny dynamic + filtered dataframe/table output with MySQL connection

Basically I'm trying to display a dataframe in R by querying it to MySQL.
I have two filters based on which the values of the dataframe/table will differ. The table is reactive based on the filters chosen by the user.
UI
ui <- fluidPage(fluidRow(
column(4,radioButtons("Stocks", "Stock Number",
choices = c(1: 2),selected='1')),
column(4,radioButtons("Funds", "Fund Name",
choices = list("W" = 1, "L" = 2),selected='1')),
column(4,checkboxGroupInput("Position", "Market Position",
choices = c(1:5))),
tableOutput("values")
)
SERVER
server <- function(input, output)
{
tableValues<-reactive({
df<-dbSendQuery(mydb,paste0("SELECT STOCKS,FUNDS,POSITION,INVESTMENTS FROM
SUMMARY WHERE USERNAME='1223' and STOCKS=",input$Stocks," AND
FUNDS='",input$Funds,"'
AND POSITION=",input$position,";"))
return(df)
})
output$values <- renderTable({
tableValues()})
}
This is what I have now but this doesn't seem to work. Any suggestions on how to display the dataframe/table and make it reactive based on the filters chosen?
Thanks!
Error: error- "cannot coerce class 'structure("MySQLResult", package = "RMySQL")' to a data.frame". That's because you've not fetched the data.
server <- function(input, output)
{
tableValues<-reactive({
query<-dbSendQuery(mydb,paste0("SELECT STOCKS,FUNDS,POSITION,INVESTMENTS FROM
SUMMARY WHERE USERNAME='1223' and STOCKS=",input$Stocks," AND
FUNDS='",input$Funds,"'
AND POSITION=",input$position,";"))
df = fetch(query, n = -1)
return(df)
})
output$values <- renderTable({
tableValues()})
}
https://www.rdocumentation.org/packages/DBI/versions/0.2-1/topics/dbSendQuery

R Shiny: Table object not found in reactive RMySQL query in shiny app

[EDIT]: solution by agstudy worked for me.
I have a shiny app that allows users to toggle between three tables in a MySQL database. Users can select a table which is used by renderTable to generate the object.
I have put if statements in renderTable to respond to the users' selected table.
When I run the app, any table fails to print and cannot be viewed.
server.R
library(shiny)
library(RMySQL)
con <- dbConnect(RMySQL::MySQL(),user="x",password="x",host="dbhost",dbname="db")
shinyServer(function(input, output) {
data <- reactive({
selectInput("input$data", "Choose your Input:", choices = c('data1'='1','data2'='2', 'data3'='3'))
})
output$table <- renderTable({
if(input$data == data1){
query1 <- reactive({ "SELECT *
FROM data1
ORDER BY var1, var2"})
reactive({dbGetQuery(con,query1())})
head(data())
} else if(input$data == data2){
query1 <- reactive({ "SELECT *
FROM data2
ORDER BY var1, var2"})
reactive({dbGetQuery(con,query1())})
head(data())
} else if(input$data == data3){
query1 <- reactive({ "SELECT *
FROM data3
ORDER BY var1, var2"})
reactive({dbGetQuery(con,query1())})
head(data())
} else print("Select a dataset")
})
})
ui.R
library(shiny)
library('RMySQL')
shinyUI(navbarPage("Test",
tabPanel("Test",
sidebarLayout(
sidebarPanel(
selectInput("data", label = "Data set",
choices = c("", "data1", "data2", "data3"))
),
mainPanel(
tableOutput("table")
)
))
))
Your problem here is not in any case related to MySQLserver but there is a no UI logic. Programming in Shiny is not easy if you don't isolate your code parts:
inputs: defined in your ui interface
reactive functions : should change each time you change your input
outputs: be refreshed once the input data is changed by the reactive function.
You miss-understand the reactive.The basic idea is that your don't need to refresh your UI manually, it should be done automatically once the input parameter is changed.
Here I am rewriting completely your code using the Shiny logic:
library(RMySQL)
library(shiny)
## this a public function that will be used
## in the server side to connect to the data base
## and retrieve data
get_data <-
function(query){
on.exit(dbDisconnect(conn)) ## important to close connection
conn <- dbConnect("MySQL",user="xuser",
password="xpws",
host="xhost",
dbname="xdbname")
dbGetQuery(con,query)
}
server <- shinyServer(
function(input, output) {
## the reactive engine that will refresh query
## each time input changed
query <- reactive( sprintf("SELECT *
FROM %s
ORDER BY var1, var2",input$data)
)
## simply displaying reactive inputs
output$table <- renderTable(
if(input$data!="") get_data(query())
)
})
## define ui elements by step
## for easy indenting
ui_panel <-
tabPanel("Test",
sidebarLayout(
sidebarPanel(
selectInput("data", label = "Data set",
choices = c("","data1", "data2", "data3"))
),
mainPanel(
tableOutput("table")
)
)
)
ui <- shinyUI(navbarPage("Test",ui_panel))
runApp(list(ui=ui,server=server))

CSV quick plot error

I would like to use the CSV quick plot application to analyze data however even with all the packages installed the app continues to show an error. The error message is:
Error in file(file, "rt") : cannot open the connection
Warning in run(timeoutMs) :
cannot open file
The code is below:
UI
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("CSV Quick Plot"),
sidebarPanel(
fileInput('infile', 'Choose file to upload',
accept = c(
'text/csv',
'text/comma-separated-values',
'text/tab-separated-values',
'text/plain',
'.csv',
'.tsv'
)
),
selectInput("plotType", label = "Select Plot Type",
c("Histogram" = "hist",
"Correlation" = "corr")),
dateInput("date", "Date:"),
submitButton("Submit")
),
mainPanel(
h3('Output Information'),
h4('File entered'),
verbatimTextOutput("ofile"),
h4('You selected plot type'),
verbatimTextOutput("oplotType"),
h4('You entered'),
verbatimTextOutput("odate"),
plotOutput('newHist')
)
))
server
library(UsingR)
library(shiny)
library(Hmisc)
library(corrplot)
wd <- getwd()
setwd(wd)
shinyServer(
function(input, output) {
output$ofile <- renderPrint({input$infile})
output$oplotType <- renderPrint({input$plotType})
output$odate <- renderPrint({input$date})
plotdata <- reactive({
filestr <- input$infile
read.csv(filestr$name)
if(is.null(input$file1))
return(NULL)
})
output$newHist <- renderPlot({
hist(plotdata())
})
# Conditional plot selection is test in progress
# corrdf <- cor(plotdata)
# output$newHist <- renderPlot({
# corrplot(corrdf, method = "circle")
# })
}
)
Please help me in getting this application to run. Thank you!
There are three problems with your code.
you're checking for if(is.null(input$file1)) but I believe you want to use input$infile
the above check should be done BEFORE read.csv because if there is no file chosen, you don't want to read a file
when reading the file you want to use filestr$datapath instead of filestr$name. The name only gives you the name of the file on the user's local machine, while the datapath gives the actual full path to the file that's been uplodaed
Here is a simplification of your app that only deals with selecting a file and reading it into csv, demonstrating all those points
runApp(shinyApp(
ui = fluidPage(
fileInput('infile', 'Choose file to upload',
accept = c(
'text/csv',
'text/comma-separated-values',
'text/tab-separated-values',
'text/plain',
'.csv',
'.tsv'
)
)
),
server = function(input, output, session) {
plotdata <- reactive({
if (is.null(input$infile)) {
return()
}
filestr <- input$infile
read.csv(filestr$datapath)
})
observe({
cat(str(plotdata()))
})
}
))