Ggplot: plot - interaction - exclude --> prevent excluded points reset - r

I would like to prevent reseting of the curve while choosing second variable to display with selectizeInput. For example in the code below we choose one value (mtcars dataset) in selectizeInput of cyl (6), and exclude one point from the curve, then we choose second value of cyl (4) to display, and therefore the previous curve with cyl=6, resets itself (the point which has been excluded, appears again).
Is there any way to prevent this behaviour and while choosing second variable the excluded point stays "excluded"?
Example code:
library(ggplot2)
library(shiny)
ui <- fluidPage(
fluidRow(
column(width = 6,
plotOutput("plot1", height = 350,
click = "plot1_click"),
selectizeInput("valuecyl", "Select value of cyl:", choices=unique(mtcars$cyl), multiple = TRUE))
)
)
server <- function(input, output) {
# For storing which rows have been excluded
vals <- reactiveValues()
data_df <- reactive({
data <- mtcars
data <- data[data$cyl %in% input$valuecyl, ]
vals$keeprows = rep(TRUE, nrow(data))
data
})
output$plot1 <- renderPlot({
data<- data_df()
keep <- data[ vals$keeprows, , drop = FALSE]
exclude <- data[!vals$keeprows, , drop = FALSE]
print(keep)
ggplot(keep, aes(wt,mpg,colour=as.factor(cyl))) + geom_point(data=keep) + geom_line(data=keep) +
geom_point(data = exclude, shape = 21, fill = NA, color = "black", alpha = 0.25)
})
# Toggle points that are clicked
observeEvent(input$plot1_click, {
data <- data_df()
res <- nearPoints(data, input$plot1_click, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
}
shinyApp(ui, server)

The issue here is that you are overwriting vals$keeprows and replacing it with rep(TRUE, nrow(data)) every time the user selects a value in your selectize.
You need to update the keeprows variable by keeping the rows that were kept by the user and adding in the new rows coming from the extra selection.
To do that, I slightly modified your code:
#added the data in the reactiveValues for convenience
vals <- reactiveValues(keeprows=logical(0),data=mtcars[0,])
#this observes the input and updates the data when the user adds a cyl value
observeEvent(input$valuecyl,{
#get the id (here rownames) of the points excluded by the user
excluded_ids <- rownames(vals$data)[!vals$keeprows]
#make the new data
vals$data=mtcars[mtcars$cyl %in% input$valuecyl,]
#keep the rows that the user had not previously excluded.
vals$keeprows = !(rownames(vals$data) %in% excluded_ids)
})
Since I added the data in the reactiveValues and removed data_df, you need to replace data_df() by vals$data in your code for this to work.

Related

In R Shiny, how to dynamically expand the use of a function as user inputs expand?

The following MWE code interpolates user inputs (Y values in 2-column matrix input grid in sidebar panel, id = input1) over X periods (per slider input in sidebar, id = periods). The custom interpolation function interpol() is triggered in server section by results <- function(){interpol(...)}. User has the option to add or modify scenarios by clicking on the single action button, which triggers a modal housing a 2nd expandable matrix input (id = input2). Interpolation results are presented in the plot in the main panel. So far so good, works as intended.
As drafted, the results function only processes the first matrix input including any modifications to it executed in the 2nd matrix input.
My question: how do I expand the results function to include scenarios > 1 added in the 2nd expandable matrix input, and automatically include them in the output plot? I've been wrestling with a for-loop to do this but don't quite know how. I've avoided for-loops, instead relying on lapply and related. But in practice a user will not input more than 20-30 scenarios max and perhaps a for-loop is a harmless option. But I'm open to any solution and am certainly not wedded to a for-loop!
MWE code:
library(shiny)
library(shinyMatrix)
interpol <- function(a,b){ # a = periods, b = matrix inputs
c <- rep(NA,a)
c[1] <- b[1]
c[a] <- b[2]
c <- approx(seq_along(c)[!is.na(c)],c[!is.na(c)],seq_along(c))$y # this interpolates
return(c)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(uiOutput("panel"),actionButton("showInput2","Modify/add interpolation")),
mainPanel(plotOutput("plot1"))
)
)
server <- function(input, output, session){
results <- function(){interpol(req(input$periods),req(input$input1))}
output$panel <- renderUI({
tagList(
sliderInput('periods','Interpolate over periods (X):',min=2,max=12,value=6),
uiOutput("input1"))
})
output$input1 <- renderUI({
matrixInput("input1",
label = "Interpolation 1 (Y values):",
value = matrix(if(isTruthy(input$input2)){c(input$input2[1],input$input2[2])}
else {c(1,5)}, # matrix values
1, 2, # matrix row/column count
dimnames = list(NULL,c("Start","End")) # matrix column header
),
rows = list(names = FALSE),
class = "numeric")
})
observeEvent(input$showInput2,{
showModal(
modalDialog(
matrixInput("input2",
label = "Automatically numbered scenarios (input into blank cells to add):",
value = if(isTruthy(input$input2)){input$input2}
else if(isTruthy(input$input1)){input$input1},
rows = list(names = FALSE),
cols = list(extend = TRUE,
delta = 2,
delete = TRUE,
multiheader=TRUE),
class = "numeric"),
footer = modalButton("Close")
))
})
observe({
req(input$input2)
mm <- input$input2
colnames(mm) <- paste(trunc(1:ncol(mm)/2)+1, " (start|end)")
isolate(updateMatrixInput(session, "input2", mm))
})
output$plot1 <-renderPlot({
req(results())
plot(results(),type="l", xlab = "Periods (X)", ylab = "Interpolated Y values")
})
}
shinyApp(ui, server)
As a user can (presumably) add only one scenario at a time, I don't think a for loop is going to help. The way I handle situations like this is to bind additional data to the appropriate reactive in an observeEvent. This will then trigger updates in the necessary outputs automatically. Here's a MWE to illustrate the technique.
library(shiny)
library(tidyverse)
ui <- fluidPage(
actionButton("add", "Add scenario"),
plotOutput("plot"),
)
server <- function(input, output, session) {
v <- reactiveValues(results=tibble(Scenario=1, X=1:10, Y=runif(10)))
observeEvent(input$add, {
newData <- tibble(Scenario=max(v$results$Scenario) + 1, X=1:10, Y=runif(10))
v$results <- v$results %>% bind_rows(newData)
})
output$plot <- renderPlot({
v$results %>% ggplot() + geom_point(aes(x=X, y=Y, colour=as.factor(Scenario)))
})
}
shinyApp(ui, server)

Select and scale variables in shiny app dynamically

I have a shiny app where I want the user to be able to select which variables to keep in the final data frame and then also select which variables to scale into a percent. I have this working, but I am running into a little puzzle. The problem is if the user decides they want to add an additional variable (or remove one), they have to redo the scaling. This could be a problem if my users have many columns they are working on. How can I keep the scaling work the user has already done, while allowing for the addition or removal of variables from the final data frame?
library(shiny)
library(tidyverse)
library(DT)
# Define UI
ui <- fluidPage(
checkboxGroupInput("select_var", label = "Select Variables"),
selectInput("scalescore", label = NULL, choices = c("")),
actionButton("scale", "Scale Scores"),
DT::dataTableOutput("table")
)
# Define server
server <- function(session, input, output) {
# define the reactive values
values <- reactiveValues(df_final = NULL)
# dynamically generate the variable names
observe({
vchoices <- names(mtcars)
updateCheckboxGroupInput(session, "select_var", choices = vchoices)
})
# dynamically generate the variables to scale
observe({
vchoices <- names(values$df_final)
updateSelectInput(session, "scalescore", choices = vchoices)
})
# select the variables based on checkbox
observe({
req(input$select_var)
df_sel <- mtcars %>% select(input$select_var)
values$df_final <- df_sel
})
observeEvent(input$scale, {
name <- rlang::sym(paste0(input$scalescore, "_scaled"))
values$df_final <- values$df_final %>% mutate(!!name := round(!!rlang::sym(input$scalescore)/max(!!rlang::sym(input$scalescore), na.rm = TRUE)*100, 1))})
output$table <- DT::renderDataTable(values$df_final)
}
# Run the application
shinyApp(ui = ui, server = server)
We will need to maintain a vector which tracks whether a variable was scaled or not. Here is how it's done,
library(shiny)
library(tidyverse)
library(DT)
# Define UI
ui <- fluidPage(
checkboxGroupInput("select_var", label = "Select Variables"),
selectInput("scalescore", label = NULL, choices = c("")),
actionButton("scale", "Scale Scores"),
DT::dataTableOutput("table")
)
server = function(input,output,session){
#Column names are static
names = colnames(mtcars)
# data scructure to store if the variable is scaled
is_scaled = logical(length(names))
names(is_scaled) = names #Set the names of the logical vector to the column names
#Update the checkbox with the column names of the dataframe
observe({
updateCheckboxGroupInput(session, "select_var", choices = names)
})
# Update the list of choices but dont include the scaled vaiables
observe({
vchoices <- names(data())
vchoices = vchoices[vchoices %in% names]
updateSelectInput(session, "scalescore", choices = vchoices)
})
#When the scle button is pressed, the vector which contains the list of scaled variables is updated
observeEvent(input$scale,{
if(is_scaled[[input$scalescore]]){
is_scaled[[input$scalescore]] <<- FALSE
}else{
is_scaled[[input$scalescore]] <<- TRUE
}
})
#Function to scale the variables
scale = function(x){
return(round(x/max(x,na.rm = T)*100,1))
}
data = reactive({
req(input$select_var)
input$scale #simply to induce reactivity
#Select the respective columns
df = mtcars%>%
select(input$select_var)
if(any(is_scaled[input$select_var])){
temp_vec = is_scaled[input$select_var] #Get a list of variables selected
true_vec = temp_vec[which(temp_vec)] #Check which ones are scaled
true_vec_names = names(true_vec) #Get the names of the variables scales
#Scale the variables respectively
df = df%>%
mutate_at(.vars = true_vec_names,.funs = funs(scaled = scale(.)))
}
return(df)
})
output$table = DT::renderDataTable(data())
}
# Run the application
shinyApp(ui = ui, server = server)
is_scaled tracks whether a particular column is scaled or not. When it is later selected, it is scaled if the value is TRUE in this vector.
Additional functionality is also added where if the scale button is pressed twice the scale column is removed.

isolate function with reactive object base on dplyr shiny

I created a simple shiny app. The goal is to create a histogram with options to manipulate the plot for each dataset. The problem is that when I change a dataset application first show me empty plot and then present a correct plot. To understand the problem I add renderText which show me a number of rows in getDataParams dataset. It seems to me that isolate function should be a solution but I tried several configurations, apparently I still do not understand this function.
library(lazyeval)
library(dplyr)
library(shiny)
library(ggplot2)
data(iris)
data(diamonds)
ui <- fluidPage(
column(3,
selectInput("data", "", choices = c('', 'iris', 'diamonds')),
uiOutput('server_cols'),
uiOutput("server_cols_fact"),
uiOutput("server_params")
),
column(9,
plotOutput("plot"),
textOutput('text')
)
)
server <- function(input, output) {
data <- reactive({
switch(input$data, diamonds = diamonds, iris = iris)
})
output$server_cols <- renderUI({
validate(need(input$data != "", "Firstly select a dataset."))
data <- data()
nam <- colnames(data)
selectInput('cols', "Choose numeric columns:", choices = nam[sapply(data, function(x) is.numeric(x))])
})
output$server_cols_fact <- renderUI({
req(input$data)
data <- data(); nam <- colnames(data)
selectizeInput('cols_fact', "Choose a fill columns:",
choices = nam[sapply(data, function(x) is.factor(x))])
})
output$server_params <- renderUI({
req(input$cols_fact)
data <- isolate(data()); col_nam <- input$cols_fact
params_vec <- unique(as.character(data[[col_nam]]))
selectizeInput('params', "Choose arguments of fill columns:", choices = params_vec,
selected = params_vec, multiple = TRUE)
})
getDataParams <- reactive({
df <- isolate(data())
factor_col <- input$cols_fact
col_diverse <- eval(factor_col)
criteria <- interp(~col_diverse %in% input$params, col_diverse = as.name(col_diverse))
df <- df %>%
filter_(criteria) %>%
mutate_each_(funs(factor), factor_col)
})
output$text <- renderText({
if(!is.null(input$cols)) {
print(nrow(getDataParams()))
}
})
output$plot <- renderPlot({
if (!is.null(input$cols)) {
var <- eval(input$cols)
print('1')
diversifyData <- getDataParams()
factor_col <- input$cols_fact
print('2')
plot <- ggplot(diversifyData, aes_string(var, fill = diversifyData[[factor_col]])) +
geom_histogram(color = 'white', binwidth = 1)
print('3')
}
plot
})
}
shinyApp(ui, server)
Here is an answer that features quite minimal changes and gives probably some deeper insights into how to control reactivity in future projects.
Your program logic features some decisions of the kind "do A if B, but not if C". But it approaches them brutally, by repeating "do A if B" until finally "not C" is true. To be more precise: You want your getDataParams to be renewed (action A) if input$cols changes (action B), but it throws errors if input$params has not changed yet (condition C).
Okay, now to the fix: We use a feature of observeEvent to evaluate if getDataParams should be recalculated. Lets read (source):
Both observeEvent and eventReactive take an ignoreNULL parameter that
affects behavior when the eventExpr evaluates to NULL (or in the
special case of an actionButton, 0). In these cases, if ignoreNULL is
TRUE, then an observeEvent will not execute and an eventReactive will
raise a silent validation error.
So the change is basically one command. Change
getDataParams <- reactive({ ... })
to
getDataParams <- eventReactive({
if(is.null(input$params) || !(input$cols_fact %in% colnames(data()))){
NULL
}else{
if(all(input$params %in% data()[[input$cols_fact]])){
1
}else{
NULL
}
}, { ... }, ignoreNULL = TRUE)
Here we check if input$cols_fact is a valid column name and if input$params has already been assigned and if so, we check if input$params is a valid list of factors for the given column. This feature was mainly designed, I suppose, to check if some element exists (input$something returning NULL if it's not defined), but we abuse it for logic evaluation and return NULL in one case and 1 (or something not NULL) in the other.
In contrast to logical tests inside the reactive environment, getDataReactive won't be changed or won't trigger change events at all, if the condition is not met.
Note: This is the minimal solution I found. With this tool and/or other changes, the code can still be fairly improved.
Full Code below.
Greetings!
library(lazyeval)
library(dplyr)
library(shiny)
library(ggplot2)
data(iris)
data(diamonds)
ui <- fluidPage(
column(3,
selectInput("data", "", choices = c('', 'iris', 'diamonds')),
uiOutput('server_cols'),
uiOutput("server_cols_fact"),
uiOutput("server_params")
),
column(9,
plotOutput("plot"),
textOutput('text')
)
)
server <- function(input, output) {
data <- reactive({
switch(input$data, diamonds = diamonds, iris = iris)
})
output$server_cols <- renderUI({
validate(need(input$data != "", "Firstly select a dataset."))
data <- data()
nam <- colnames(data)
selectInput('cols', "Choose numeric columns:", choices = nam[sapply(data, function(x) is.numeric(x))])
})
output$server_cols_fact <- renderUI({
req(input$data)
data <- data(); nam <- colnames(data)
selectizeInput('cols_fact', "Choose a fill columns:",
choices = nam[sapply(data, function(x) is.factor(x))])
})
output$server_params <- renderUI({
req(input$cols_fact)
data <- isolate(data()); col_nam <- input$cols_fact
params_vec <- unique(as.character(data[[col_nam]]))
selectizeInput('params', "Choose arguments of fill columns:", choices = params_vec,
selected = params_vec, multiple = TRUE)
})
getDataParams <- eventReactive({
if(is.null(input$params) || !(input$cols_fact %in% colnames(data()))){
NULL
}else{
if(all(input$params %in% data()[[input$cols_fact]])){
1
}else{
NULL
}
}, {
df <- isolate(data())
factor_col <- input$cols_fact
col_diverse <- eval(factor_col)
criteria <- interp(~col_diverse %in% input$params, col_diverse = as.name(col_diverse))
df <- df %>%
filter_(criteria) %>%
mutate_each_(funs(factor), factor_col)
}, ignoreNULL = TRUE)
output$text <- renderText({
if(!is.null(input$cols)) {
print(nrow(getDataParams()))
}
})
output$plot <- renderPlot({
if (!is.null(input$cols)) {
var <- eval(input$cols)
print('1')
diversifyData <- getDataParams()
factor_col <- input$cols_fact
print('2')
plot <- ggplot(diversifyData, aes_string(var, fill = diversifyData[[factor_col]])) +
geom_histogram(color = 'white', binwidth = 1)
print('3')
}
plot
})
}
shinyApp(ui, server)
To best explaining the flow - I create a picture that explain how the plot get refresh as below:
So, with no isolate code, you will any change in any change on any control on the code will trigger the change to the control on the end of arrow. In this case which end up result the plot refresh 5 times.
With the isolate code in your code from above post, you already eliminate two small arrow.
To avoid the case you mentioned with when Choose a fill columns, you need to eliminate the big arrow that I highlighted by isolate the input$cols_fact in output$plot <- renderPlot{...} reactive.
With this you still have the plot refresh two time when choose data table but I think it acceptable as you need the plot to re-active when you do Choose numeric columns
Hope this answer your questions! Having fun playing arround with Shiny!

Reactive update ot tile map using plot_click - Shiny

I am using shiny to query an SQL database. From the data I produce a tile map. I would like the user to be able to click a tile, to select data, after which the tile changes colour. I have got it working slightly but the tile changes back to the original colour almost immediately. Here is an example:
Server.R
library(data.table)
# Create example data
Row <- 1:4
Col <- 1:4
Batch <- c("A","B")
dd <- expand.grid(Row,Col, Batch)
colnames(dd) <- c("Row","Col","Batch")
#Write to memory
con <- dbConnect(RSQLite::SQLite(), ":memory:")
dbWriteTable(con, "dd", dd)
query <- function(...) dbGetQuery(con, ...)
shinyServer(function(input, output, session){
id <- eventReactive(input$do, {input$batch})
# Search by batch: either A or B. Create column "selected" to represent which tile has been clicked lower down i.e. 0 = not selected, 1=selected
wid <- reactive({
if(input$do==0) return ( )
quer <- paste("Select Row, Col, '0' as selected from dd where Batch='",id(),"'", sep="")
data.frame(query(quer))
})
# Output of clicked tile
output$plot_clicked_points <- renderDataTable({
dat <- wid()
res <- nearPoints(dat, input$plot_click,
threshold = 100, maxpoints = 1)
data.table(res)
})
#Update dataframe by changing "selected" tile to 1
update <- reactive({
dat <- wid()
res <- nearPoints(dat, input$plot_click,
threshold = 100, maxpoints = 1)
DT <- data.table(dat)
DT[(Row==res$Row & Col==res$Col), selected:=1]
})
# Produce tile map with colour of tile based on whether it is the most recently clicked i.e. "selected" should now be = 1
output$map <- renderPlot({
ggplot(update(), aes(Row,Col, fill=factor(selected))) + geom_tile(colour="white")
})
})
ui.R
library(shiny)
library(ggplot2)
library(RMySQL)
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
textInput("batch", label = "Batch ID", value=""),
actionButton("do", label = "Search")
),
mainPanel(
dataTableOutput(outputId="plot_clicked_points"),
plotOutput("map", click = "plot_click")
))))
So my question is, how do I get the colour change to stick? Maybe I need to create reactiveValues? Maybe I need a different approach altogether? Thanks
The issue is that when update is changed, the ggplot is redrawn which sets the selected points to an empty data frame. This removes all the selected points from your data frame and reverts the coloring.
You could try changing the data frame only when there is at least one selected point, I stored the data frame in a reactive value, you can access using values$data:
values <- reactiveValues()
observe({
if(input$do==0) return ( )
quer <- paste("Select Row, Col, '0' as selected from dd where Batch='",id(),"'", sep="")
print(data.frame(query(quer)))
values$data = data.frame(query(quer))
})
#Update dataframe by changing "selected" tile to 1
observe({
res <- nearPoints(values$data, input$plot_click,
threshold = 100, maxpoints = 1)
if(!is.null(res)) {
if(nrow(res)>=1){
selected <- rep(0,nrow(values$data))
selected[which(values$data$Row==res$Row & values$data$Col==res$Col)] <- 1
values$data$selected <- selected
}
}
})
# Produce tile map with colour of tile based on whether it is the most recently clicked i.e. "selected" should now be = 1
output$map <- renderPlot({
ggplot(values$data, aes(Row,Col, fill=factor(selected))) + geom_tile(colour="white")
})
Another in my opinion slightly more simple solution would be to use a reactiveVal to monitor selection. Example app.R:
library(shiny)
library(ggplot2)
library(dplyr)
dataset = expand.grid(time=paste("m_", 1:10), op=paste("om_", 1:20)) %>% mutate(wip=row_number())
server <- function(input, output) {
tileSelect <- reactiveVal(data_frame())
output$wip_map <- renderPlot({
p = ggplot(fakewip, aes(time, op, fill = wip)) + geom_tile()
if (nrow(tileSelect()) > 0) {
p + geom_tile(color="red", size=2, fill=NA, data=tileSelect())
}else{
p
}
})
observeEvent(input$plot_click, {
tileSelect(nearPoints(dataset, input$plot_click, threshold = 100, maxpoints=1))
})
# reset selection with double click
observeEvent(input$plot_dblclick, {
tileSelect(data_frame())
})
}
ui <- fluidPage(
title = "Heatmap Select",
plotOutput("wip_map", click = "plot_click", dblclick = "plot_dblclick")
)
shinyApp(ui = ui, server = server)

Shiny R - reactivity not working with conditional panel

Problem :
In my app I have two tabs in the side panel
Stats and Charts -
In stats I want to show the data frame and some descriptive stats (which works fine) based on the Data thats is being selected in main panel (select input which selects the Data) and selectGroupinput( which selects the columns of the selected data) ,
in Charts I have a drop down of the columns of the selected Data and want to show bar charts for them .
Now this works smoothly when I dont put a conditional panel for selectgroupinput to be shown only in the Stat Tab and Drop down selectinput only in the Chart tab ( in the sense that the columns automatically gets updated when selecting a Data .
Now when I put conditional panel around that ,it works smooth for the Stat tab but in Charts tab the the Columns does not function properly on changing the data set .
I have to click the Stat tab and again click back to Charts tab to make the actual columns of the data appear in the drop down -in short the reactivity of the Data set and Column drop down is not functioning as it should be .
I have a reproducible code sample here :
https://gist.github.com/creepystranger/9168c1430c7d468fc5fb
code :
server.r
ibrary(shiny)
#library(RODBC)
library(ggplot2)
#library(shinyjs)
#stat_helper_function to be used in rendering stat table
summary <- function(x) {
funs <- c(mean, median, sd, mad, IQR,max,min)
lapply(funs, function(f) f(x, na.rm = TRUE))
}
make_stat <- function(data){
numeric_columns <- sapply(data,is.numeric)
stat_table <- sapply(data[,numeric_columns],summary)
rows <- c("Mean","Median","SD","MAD","IQR","Max","Min")
df <- data.frame(stat_table,row.names = rows)
}
#sample prototypeof Data
data_sets <- c("iris","diamonds")
shinyServer(function(input, output) {
output$choose_dataset <- renderUI({
selectInput("Dataset",label = "choose a dataset",as.list(data_sets))
})
output$choose_columns <- renderUI({
if(is.null(input$Dataset))
return()
dat <<- get(input$Dataset) # make it globally accessable _saves the pain of multiple load of the data
colnames <- names(dat)
checkboxGroupInput("columns", "Choose columns",
choices = colnames,
selected = colnames)
})
output$plot_control <- renderUI({
if(is.null(input$Dataset))
return()
dat #<- get(input$Dataset)
numeric_columns <- sapply(dat,is.numeric)
num_dat <- dat[,numeric_columns]
colnames <- names(num_dat)
selectInput("selectize","For the X axis and Y axis",choices=colnames)
})
output$histo_gram <- renderPlot({
if(is.null(input$Dataset))
return()
#z<- matrix(num_dat,ncol = ncol(num_dat))
numeric_columns <- sapply(dat,is.numeric)
num_dat <- dat[,numeric_columns]
num_dat
if (is.null(input$selectize) || !(input$selectize %in% names(num_dat)))
return()
z <- num_dat[,input$selectize]
# bw <- diff(range(z)) / (2 * IQR(z) / length(z)^(1/3))
qplot(z,geom ="histogram")
})
output$mytable1 <- renderDataTable({
if(is.null(input$Dataset))
return()
#dat <- get(input$Dataset)
dat
if (is.null(input$columns) || !(input$columns %in% names(dat)))
return()
# Keep the selected columns
dat <- dat[, input$columns, drop = FALSE]
dat}, options=list(lengthMenu = c(5, 8, 10), pageLength = 5)
)
output$stat_table <- renderTable({
dat #<- get(input$Dataset)
num_dat <- dat[,input$columns,drop=FALSE]
make_stat(num_dat)
}
)
})
ui.r
# This is the user-interface definition of a Shiny web application.
# You can find out more about building applications with Shiny here:
#
# http://www.rstudio.com/shiny/
#
library(shiny)
library(ggplot2)
shinyUI (pageWithSidebar(
headerPanel("Creepy-Stats"),
sidebarPanel(
uiOutput("choose_dataset"),
br(),
conditionalPanel(
condition ="input.conditionedPanels == 'Stats'",uiOutput("choose_columns")),
conditionalPanel(condition ="input.conditionedPanels == 'Charts'" ,uiOutput("plot_control")), width = 2
#
# uiOutput("choose_columns"),uiOutput("plot_control"),width = 2
),
mainPanel(
tabsetPanel(
tabPanel("Stats",
div (class='row',
div(dataTableOutput("mytable1"),class="span10"),
div(tableOutput("stat_table"),class="span5")
),id = "conditionedPanels"
)
,
tabPanel("Charts",
div(class='row',
div(plotOutput("histo_gram"),class="span10"))
),id = "conditionedPanels"
),width = 10
)
))

Resources