I am work with flexdashboard.I already find some tempalate example (https://jjallaire.shinyapps.io/shiny-biclust/ ) and now I want to adapt in accordance with my needs. But I face with one problem.
Namely here I already used reactive function and below you can see my code from function.
num<-reactive(as.integer(input$clusterNum)
Selection here is made with selection number from 1 to 5. After selection from drop down menu and select one of number from 1 to 5, this selection going to next block of code and select appropirate cluster. You can see code below
renderTable(
BicatYeast[which(res#RowxNumber[, num()]), which(res#NumberxCol[num(), ])]
)
So far so good. But now I want to try to use this kind selection on my data. My dataset is list with two tables (table 1 and table 2) . You can see how is look in R.
Now I want to use same command for selection of my data and I tryed with command line
data[which(num()]
but this not work.
So can anybody help me how solve this problem and select table 1 of my list ?
This is how to display one table of the list:
library(shiny)
# example data
data <- list(
iris,
ggplot2::mpg,
iris,
iris,
iris
)
ui <- fluidPage(
numericInput("clusterNum", label = "Cluster number", value = 1, min = 1, max = 5, step = 1),
tableOutput("table")
)
server <- function(input, output, session) {
output$table <- renderTable({
data[[input$clusterNum]]
})
}
shinyApp(ui, server)
Related
Im trying to follow the examples (https://yihui.shinyapps.io/DT-edit/) for editing a DT table in R shiny, but cannot seem to get it to update correctly. Below is a toy example. As a test, table edits should print to the main panel when hitting "go," but the edits are not passed along. I am not sure what I am doing wrong.
Second, I would like to be able to work with the table as an R object that I can pass along to other aspects of the code (e.g., pass one of the columns as a vector to something else). But I am not 100% sure how to do this. Ideally this might be something like "hot_to_r" in the rhandsontable package, but I am not sure how this might be done for DT. Thank you in advance for your help.
library(shiny)
library(DT)
ui <- fluidPage(
titlePanel("use DT package"),
sidebarLayout(
sidebarPanel(
h4('A Table Using Server-side Processing'),
fluidRow(
column(2),
column(8, DT::dataTableOutput('tb')),
column(2)
),
actionButton("go", "go")
),
mainPanel(
verbatimTextOutput("test"), #to test if the table updates
)))
server <- (function(input, output, session) {
DF <- data.frame(Original_Name = rep("place holder", 3), New_Name = rep("place holder", 3), stringsAsFactors = FALSE)
output$tb <- renderDT(DF, selection = "none", server = TRUE, editable = "all")
# update edited cells ("all")
observeEvent(input$tb_cell_edit, {
DF <<- editData(DF, input$tb_cell_edit, 'tb')
})
#print the table to test that it works
#but what I really want is to create an R object that I can use
#to extract column "Original_Name" and "New_Name"
observeEvent(input$go,{
output$test<-renderPrint(DF)
})
})
runApp(list(ui=ui,server=server), launch.browser=TRUE) #launch in browser
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 have a Shiny app which can either display a plot or print a dataframe. While it does both, it only prints the 1st 10 rows of the data frame and add "... 86 more rows". I would like to display at least 40 rows of the data frame. I tried both a & head(a, n=50) but it displays only 10 rows of the total. How can I make it display more rows.
This is what I have
server.R
output$IPLMatch2TeamsPlot <- renderPlot({
printOrPlotIPLMatch2Teams(input, output)
})
# Analyze and display IPL Match table
output$IPLMatch2TeamsPrint <- renderPrint({
a <- printOrPlotIPLMatch2Teams(input, output)
head(a,n=50)
#a
})
output$plotOrPrintIPLMatch2teams <- renderUI({
# Check if output is a dataframe. If so, print
if(is.data.frame(scorecard <- printOrPlotIPLMatch2Teams(input, output))){
verbatimTextOutput("IPLMatch2TeamsPrint")
}
else{ #Else plot
plotOutput("IPLMatch2TeamsPlot")
}
})
ui.R
tabPanel("Head to head",
headerPanel('Head-to-head between 2 IPL teams'),
sidebarPanel(
selectInput('matches2TeamFunc', 'Select function', IPLMatches2TeamsFuncs),
selectInput('match2', 'Select matches', IPLMatches2Teams,selectize=FALSE, size=20),
uiOutput("selectTeam2"),
radioButtons("plotOrTable1", label = h4("Plot or table"),
choices = c("Plot" = 1, "Table" = 2),
selected = 1,inline=T)
),
mainPanel(
uiOutput("plotOrPrintIPLMatch2teams")
)
When you know your output is going to be a data.frame and not just any random bit of text, you can choose an output optimized for displaying tabular data. You could try renderTable and tableOutput instead of your renderPrint and verbatimTextOutput. Another option is renderDataTable from the DT package. This create a table that puts extra rows on different pages so you can acces all rows and you can modify how many rows it will show at any time.
For example, replacing your current renderPrint with the following:
output$IPLMatch2TeamsPrint <- DT::renderDataTable({
a <- printOrPlotIPLMatch2Teams(input, output)
datatable(a,
options = list(
"pageLength" = 40)
)
})
and replacing your verbatimTextOutput("IPLMatch2TeamsPrint") with DT::dataTableOutput("IPLMatch2TeamsPrint") Should give you a table with 40 rows and the option to see more rows as different pages in the table.
You might want to change the names from print to table as well for clarity since you're not just printing anymore.
I use
output$hot <- renderRHandsontable(rhandsontable(DF))
to get a table.
All works fine but I would like to allow the user to select certain columns only (implemented with shiny::updateSelectizeInput()). the data should then be updated in the full data table and not only in the columns selected. I googled but could only find a very bad description in java. Can someone help me out with this?
as requested an example:
DF = data.frame(matrix(rnorm(20), nrow=10))
rhandsontable(DF)
This is a few years late, and I will note that I don't think this will completely solve the issue as it doesn't use "updateSelectizeinput()" as requested by the OP, plus I must not be handling the select input correctly as one column always shows, but for anyone looking for a start, here is an example:
library(shiny)
library(rhandsontable)
ui <- fluidPage(
selectInput("Select", "Select", names(mtcars), multiple = T, selected = names(mtcars)),
rHandsontableOutput("cars")
)
server <- function(input, output, session) {
DF<-reactiveValues(DF = mtcars, Select = NULL)
observeEvent(input$Select,{
DF$Select <- input$Select
})
output$cars<-renderRHandsontable({
rhandsontable(DF$DF, rowHeaders = NULL)%>%
hot_cols(colWidths = ifelse(names(DF$DF) %in% DF$Select == T, 150, 0.1))
})
}
shinyApp(ui, server)
It uses 0.1 as a column width to effectively hide the column, leaving the original data frame in tact.
I have a graph that I only want to display if it wouldn't take too long to render, otherwise I want to have a button the user can press to render it.
My problem is that the graph renders before being hidden in some circumstances.
Open this minimally reproduced example up and try the following steps
UI.r
shinyUI(fluidPage(
titlePanel("when to render"),
fluidRow(
column(2,radioButtons("TheChoice", label= "choices",
choices = list("only one" = 1,"just two" = 2,"three" = 3,"all four" = 4),selected = 1))
),
fluidRow(
mainPanel(tabsetPanel(tabPanel("Blank page",NULL),
tabPanel("plot output",
verbatimTextOutput("validRows"),
conditionalPanel(
condition = "output.validRows < 3",
plotOutput("thePlot")
))
)
)
)
))
Server.r
library(shiny)
library(ggplot)
library(reshape2)
`[` <- function(...) base::`[`(...,drop=FALSE)
myTable <- matrix(1:20,ncol=4)
colnames(myTable) <- c("Index","catone","cattwo","catthree")
rownames(myTable) <- c("first","second","third","fourth","fifth")
shinyServer(function(input, output,session) {
TableIndex <- reactiveValues(X = NULL)
observe({
print("updating TableIndex")
if(input$TheChoice == 1) TableIndex$X <- 1 else TableIndex$X <- 1:input$TheChoice
})
graphedTableData <- reactive({
return(myTable[TableIndex$X,2])
})
dataSubset <-
reactive({
print(paste0("calculating subset with ", length(TableIndex$X)," rows"))
renderedData <- graphedTableData()
renderedData2 <- melt(renderedData,id=rownames(renderedData))
colnames(renderedData2)<-c("catone","cattwo","catthree")
return(renderedData2)
})
output$thePlot <- renderPlot({
print(paste0("Rendering Plot with ", length(TableIndex$X)," rows"))
theSubset <- dataSubset()
ggplot(data=theSubset,aes(x=catone,y=cattwo,colour=catthree)) +
geom_line()
})
output$validRows <- reactive({print("updating validRows");length(TableIndex$X)})
})
click on the plot output tab: a plot renders and is then output (with one data row used)
select choice 2: a plot renders and is then output (with two data rows used)
select choice 3: a plot renders and is THEN hidden :(
select choice 4: nothing is rendered/output (good)
now going between 3 and 4, nothing happens (good)
By looking at the console output, you can see that "TableIndex" is updated first, so it seems like this should never render with choice 3, since the plot would immediately disappear before it was updated. Presumably, that updating already triggered the reactive() and renderPlot() though.
How do I prevent these functions from executing in this order? I know I could just short circuit the reactive() and renderPlot() by checking TableIndex$X in the first line, but that seems hacky and I'm just learning shiny so I'm hoping for a cleaner solution
Bonus points if you implement the appearance of a render button instead of displaying nothing for choices 3 and 4. I've yet to attempt that but I believe it would be something with renderUI() ?
(TableIndex is calculated separately and then accessed in this way because in real life, it is finding the relevant indices from a large table and then applying those same indices to other tables. Assume that the index finding is fast)