i got my first Shiny App working - at least nearly. The code works find and in simplified form looks like
shinyUI(fluidPage(
titlePanel('Tableau Workbook'),
sidebarPanel(
uiOutput("select")
),
mainPanel(
tableOutput("Columns1"))
))
shinyServer(function(input,output){
output$select <- renderUI({
selectInput("dataset", "Names", as.list(files))
})
output$columns1 <- renderTable({
f<- myfunction(input$dataset)
f[[3]]
})
})
I need to modify "dataset" before it can be used in renderTable(). I tried
output$columns1 <- renderTable({
dataset<- lookuptable[which(dataset== lookuptable$table1),2 ]
f<- myfunction(input$dataset)
f[[3]]
})
The SelectInput shows a selection, from which the user can choose. What the extraline is doing: take the chosen item, look up the matching value in the lookuptable. This value is then fed into the function. The lookuptable is a dataframe with two columns and n rows..
However, when I add the extraline the visualization is broken. Has anyone an idea why?
Thanks a million for any help!
Related
I am trying to create a shiny app that has a rhandsontable in it. I want rhandsontable to be able to update its values in one of its columns if the corresponding values in another column is selected/ checked. So far, I have been able to use reactive / observe events to change the output values between two objects but i am unable to wrap my head around it , i.e, how do i make once column of rhandsontable reactive to another column in the same table ?
Here is a simple example of what i am trying to build:
library(shiny)
library(rhandsontable)
ui <- fluidPage(
rHandsontableOutput('table')
)
server <- function(input,output,session)({
data <- data.frame(c1=c(5,10,15), c2=c(3,6,9) , diff=c(0,0,0), select= as.logical( c(FALSE,FALSE,FALSE)))
output$table <- renderRHandsontable({
rhandsontable(data)
})
})
shinyApp(ui = ui, server = server)
So if i check the column 'Select', column 'diff' should produce the difference between column c1 & c2
From what I understand, your goal is to do some calculation depending on the values of some other column. So if for example a box of the third column is checked, you might want to compute the difference between elements of column 1 and 2.
If you had just a data frame, that would be easy, wouldn't it? Well, this is possible using reactive values. The main idea is that you can store the rhandsontable in a data frame in the backend, modify the data frame and then render the modified data frame once again back in the handsontable.
I hope this helps:
For a more detailed example on reactive values you can see
this: http://stla.github.io/stlapblog/posts/shiny_editTable.html
and this : https://www.youtube.com/watch?v=BzE1JmC0F6Q&list=PL6wLL_RojB5wXR3NR3K38sIvexZ_45alY&index=3
library(rhandsontable)
library(shiny)
ui <- fluidPage(
mainPanel(
rHandsontableOutput("hot")
)
)
server = function(input, output, session){
df<- data.frame(c1=c(5,10,15), c2=c(3,6,9) , diff=c(0,0,0), select= as.logical( c(FALSE,FALSE,FALSE)))
values <- reactiveValues(data = df)
observe({
if(!is.null(input$hot)){
values$data <- as.data.frame(hot_to_r(input$hot))
isolate(values$data[,'diff'] <- ifelse(values$data[,'select'], values$data[,'c1']-values$data[,'c2'] ,0))
print(values$data)
output$hot <- renderRHandsontable({
rhandsontable(values$data)
})
}
})
output$hot <- renderRHandsontable({
rhandsontable(values$data)
})
}
shinyApp(ui, server)
I have encountered this problem while developing an app, and reproduced it here in a simplified script using Fruits df.
Basically, i have selectInput box to select a Year, which is a column in Fruits. I create unique list of Years, and feed it into selectInput box.
Then, ideally, i wanted my plot to display only the records for the year I selected. However, as you'll see in my code - the second you uncomment a block of 3 lines to accomplish that, - the plot stops displaying even though there doesn't seem to be any errors. Anybody knows why is this? Thanks in advance!!!
Related question - while debugging this i saw that the input$explore_year is at first "Null". I'm trying to handle this in the code but not sure why the selected="2010" doesn't take care of it automatically.
library(shiny)
library(googleVis)
library(DT)
listOfFruits <- sort(unique(Fruits$Year), decreasing = FALSE)
ui <- fluidPage(title = "Fruits Bug Recreated",
fluidRow(
column(3,
wellPanel(
uiOutput("choose_year"),
br()
)),
column(9,
tags$hr(),
htmlOutput("view")
)),
fluidRow(DT::dataTableOutput("tableExplore"))
)
server <- function(input, output) {
output$view <- renderGvis({
#Uncomment these 3 lines to see how the plot stops displaying.
# local_exloreYear <- input$explore_year
# if (is.null(local_exloreYear)) {local_exloreYear <- "2010"}
# FruitsSubset <- subset(Fruits, Year == local_exloreYear)
#------------I wanted to use the commented line below instead of the
#that follows
#gvisBubbleChart(FruitsSubset, idvar="Fruit",
#-------------
gvisBubbleChart(Fruits, idvar="Fruit",
xvar="Sales", yvar="Expenses",
colorvar="Year", sizevar="Profit",
options=list(
hAxis='{minValue:70, maxValue:125, title:"Sales"}',sortBubblesBySize=TRUE,
vAxis='{title: "Expenses",minValue:60, maxValue:95}'
))
})
# Drop-down selection box for dynamic choice of minutes in the plans to compare
output$choose_year <- renderUI({
selectInput("explore_year", "Select Year", as.list(listOfFruits),selected ="2010")
})
output$tableExplore <- DT::renderDataTable(DT::datatable({
FruitsSubset <- subset(Fruits, Fruits$Year == input$explore_year)
myTable <-FruitsSubset[,c(1,2,3,4,5,6)]
data <- myTable
data
},options = list(searching = FALSE,paging = FALSE)
))
}
shinyApp(ui = ui, server = server)
Like i wrote in the comments you can solve it by make the rendering conditional on the input being non-NULL.
output$view <- renderGvis({
if(!is.null(input$explore_year)){
...
}
})
Nevertheless, I donĀ“t think it is really intended that you have to do that, as in other render functions it is not required e.g. in the DT::renderDataTable(), where you also use the same input (being NULL initially).
Therefore, I would suggest reporting it as a bug.
I am trying to create numeric boxes for all column names in a data set. I have written below code but this displays a blank page. Not sure what the error is. Any suggestions?
library(shiny)
library(readr)
shinyApp(
ui <- fluidPage(
uiOutput("TestColumns")
),
server <- function(input, output) {
data_set <- read.csv("Data/170210_Flat_File.csv")
output$TestColumns <- renderUI({
for(i in names(data_set)){
numericInput(i, i,30)
}}
)})
First off, when you ask questions you should ALWAYS post a minimal reproducible example. That is basically something that we can run to replicate the issue you are having so that it is much easier for us to help you. This way we don't have to go about using different data, trying to figure out exactly what your error is. See this link for a good intro: How to make a great R reproducible example?
Next to your question - since you didn't explicitly post an error you were seeing or explicitly state what your issue was I'm going to go ahead and assume that your issue is that you don't see any UI's popping up when you run your Shiny App (this is what I got when I tried running your code with different sample data).
The reason you aren't seeing anything is because you aren't returning any objects from your for loop. If you really wanted to do a for loop you would have to loop through, store everything in a list, then return that list. Note that I had to use R's built in data because you didn't provide any. Something like this would work:
shinyApp(
ui <- fluidPage(
#numericInput("test","test",30),
uiOutput("TestColumns")
),
server <- function(input, output) {
data_set <- mtcars
output$TestColumns <- renderUI({
L<-vector("list",length(names(data_set)))
for(i in names(data_set)){
L[[i]]<-numericInput(i, i,30)
}
return(L)
})})
This should give you your desired result. However, the above is unnecessarily complicated. I suggest you use an lapply instead. Something like this is much better in my opinion:
shinyApp(
ui <- fluidPage(
#numericInput("test","test",30),
uiOutput("TestColumns")
),
server <- function(input, output) {
data_set <- mtcars
output$TestColumns <- renderUI({
lapply(names(data_set),function(x){numericInput(x,x,30)})
})})
ui <- bootstrapPage(
fluidRow(
column(4,offset = 2,
tags$h4("numeric inputs"),
uiOutput('mtcars_numerics') # These will be all the numeric inputs for mtcars
),
column(6,
tags$h4("current input values"),
verbatimTextOutput('show_vals') # This will show the current value and id of the inputs
)
)
)
server <- function(input, output, session){
# creates the output UI elements in the loop
output$mtcars_numerics <- renderUI({
tagList(lapply(colnames(mtcars), function(i){ # must use `tagList` `
column(3,
numericInput(
inputId = sprintf("mt_col_%s",i), # Set the id to the column name
label = toupper(i), # Label is upper case of the col name
min = min(mtcars[[i]]), # min value is the minimum of the column
max = max(mtcars[[i]]), # max is the max of the column
value = mtcars[[i]][[1]] # first value set to the first row of the column
))
})
)
})
# So we can see the values and ids in the ui for testing
output$show_vals <- renderPrint({
all_inputs <- names(session$input)
input_vals <- plyr::ldply(all_inputs, function(i){
data.frame(input_name = i, input_value = input[[i]],stringsAsFactors = FALSE)
})
input_vals
})
}
shinyApp(ui, server)
Results in:
I have a data-frame which is obtained after some processing. In this data-frame the user needs to choose certain criteria which the user wants to go ahead for further processing. For this there is an add button which when clicked by the user will take out the data according to the selected criteria and append to a new data frame. This new frame then goes ahead for further processing. What I seem to be stuck at is I cannot make shiny add a data-frame to another data frame when Add button is pressed. I have provided the code below. Any help will be greatly appreciated.
ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel('Testing'),
sidebarPanel(
conditionalPanel(
condition="input.tabs1=='Observe Data'",
uiOutput("item"),
actionButton("add", "Add"))
),
mainPanel(
tabsetPanel(id ="tabs1",
tabPanel("Observe Data",verbatimTextOutput("Data_table")),
tabPanel("Final Table",verbatimTextOutput(outputId='plot'))
)
)
))
server.R
library(shiny)
library(dplyr)
chosen_category<-data.frame()
shinyServer(function(input, output) {
data<-data.frame(Names=c("A","A","A","B","B","B","C","C","A"),Values=c(1,2,3,4,5,654,3,2,2))
output$item<-renderUI({
selectInput("category","Categories",as.character(unique(data$Names)))
})
filtdata<-reactive({
p<-data
p_filt<-data%>%
filter(Names %in% input$category)
p_filt
})
output$Data_table<-renderPrint({
filtdata()
})
observe({
input$add
chosen_category <<- rbind(chosen_category, filtdata())
})
final_data <- reactive({
chosen_category
})
})
If you want to say print the final data frame in your Final Data tab, you can add a dependency to the action button in a renderPrint rather than in an observe. I remove the observe and final_data expression and added this to your server.R:
output$plot<-renderPrint({
input$add
chosen_category <<- rbind(chosen_category, filtdata())
chosen_category
})
This prints the final data frame in the last tab of your ui.R.
I am trying to have multiple html outputs in my shiny App but it seems like it can only show one at a time.
My UI is:
# ui.R
shinyUI(
mainPanel(
tableOutput("view"),
plotOutput("view2")
))
And my server is:
# server.R
library(googleVis)
library(RMySQL)
shinyServer(function(input, output) {
datasetInput <- reactive({
"try2" = subset(try1, idCampaign == input$inputId)
})
output$view <- renderGvis({
gvisTable(datasetInput(),options=list(width=1000, height=270, col='blue'))
})
output$view2 <- renderGvis({
gvisScatterChart(datasetInput2())
})
})
in the output to view2 you use datasetInput2() , this should be datasetInput(). Here datasetInput() just represents a dynamic version of a dataframe, you can use it in as many functions as you want, there is no need to index it.
alternatively i think you can use the tabsetPanel to divide your main page into certain parts and assign output objects to each of your tabPanel.