0

I'm creating a shiny app and i'm letting the user choose what data that should be displayed in a plot and a table. This choice is done through 3 different input variables that contain 14, 4 and two choices respectivly.

ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
selectInput(inputId = "DataSource", label = "Data source", choices = 
c("Restoration plots", "all semi natural grasslands")),

selectInput(inputId = "Variabel", label = "Variable", choices = 
choicesVariables)),
#choicesVariables definition is omitted here, because it's very long but it 
#contains 14 string values

selectInput(inputId = "Factor", label = "Factor", choices = c("Company 
type", "Region and type of application", "Approved or not approved 
applications", "Age group"  ))

),

dashboardBody(
plotOutput("thePlot"),
tableOutput("theTable")
))

This adds up to 73 choices (yes, i know the math doesn't add up there, but some choices are invalid). I would like to do this using a lookup table so a created one with every valid combination of choices like this:

rad1<-c(rep("Company type",20), rep("Region and type of application",20), 
rep("Approved or not approved applications", 13), rep("Age group", 20))

rad2<-choicesVariable[c(1:14,1,4,5,9,10,11, 1:14,1,4,5,9,10,11, 1:7,9:14, 
1:14,1,4,5,9,10,11)]

rad3<-c(rep("Restoration plots",14),rep("all semi natural grasslands",6), 
rep("Restoration plots",14), rep("all semi natural grasslands",6), 
rep("Restoration plots",27), rep("all semi natural grasslands",6))

rad4<-1:73

letaLista<-data.frame(rad1,rad2,rad3, rad4)

colnames(letaLista) <- c("Factor", "Variabel", "rest_alla", "id")

Now its easy to use subset to only get the choice that the user made. But how do i use this information to plot the plot and table without using a 73 line long ifelse statment?

I tried to create some sort of multidimensional array that could hold all the tables (and one for the plots) but i couldn't make it work. My experience with these kind of arrays is limited and this might be a simple issue, but any hints would be helpful!

My dataset that is the foundation for the plots and table consists of dataframe with 23 variables, factors and numerical. The plots and tabels are then created using the following code for all 73 combinations

s_A1 <- summarySE(Samlad_info, measurevar="Dist_brukcentrum", 
groupvars="Companytype")
s_A1 <- s_A1[2:6,]

p_A1=ggplot(s_A1, aes(x=Companytype, 
y=Dist_brukcentrum))+geom_bar(position=position_dodge(), stat="identity") +
geom_errorbar(aes(ymin=Dist_brukcentrum-se, 
ymax=Dist_brukcentrum+se),width=.2,position=position_dodge(.9))+
scale_y_continuous(name = "") + scale_x_discrete(name = "")

where summarySE is the following function, burrowed from cookbook for R

summarySE <- function(data=NULL, measurevar, groupvars=NULL, na.rm=TRUE,
                    conf.interval=.95, .drop=TRUE) {


# New version of length which can handle NA's: if na.rm==T, don't count them
length2 <- function (x, na.rm=FALSE) {
  if (na.rm) sum(!is.na(x))
  else       length(x)
}

# This does the summary. For each group's data frame, return a vector with
# N, mean, and sd
datac <- ddply(data, groupvars, .drop=.drop,
               .fun = function(xx, col) {
                 c(N    = length2(xx[[col]], na.rm=na.rm),
                   mean = mean   (xx[[col]], na.rm=na.rm),
                   sd   = sd     (xx[[col]], na.rm=na.rm)
                 )
               },
               measurevar
)

# Rename the "mean" column    
datac <- rename(datac, c("mean" = measurevar))

datac$se <- datac$sd / sqrt(datac$N)  # Calculate standard error of the mean

# Confidence interval multiplier for standard error
# Calculate t-statistic for confidence interval: 
# e.g., if conf.interval is .95, use .975 (above/below), and use df=N-1
ciMult <- qt(conf.interval/2 + .5, datac$N-1)
datac$ci <- datac$se * ciMult

return(datac)
}

The code in it's entirety is a bit to large but i hope this may clarify what i'm trying to do.

  • That depends on how all that data is stored. Do you have multiple dataframes in a list? Do you run a query on a database dependent on the user input? Please consider adding a [reprducible example](https://stackoverflow.com/questions/48343080/how-to-convert-a-shiny-app-consisting-of-multiple-files-into-an-easily-shareable), that will make it much more easier to help you. – Florian Feb 09 '18 at 10:33
  • I've tried to clearify the question by adding more code and information on my data. A reproducible example will unfortunately be to large to add in here. I do not have a database solution, the data is all imported and created as data frames in the local environment. – Kristoffer Hellberg Feb 09 '18 at 11:26
  • Hi @Kristoffer, based on your update, [this question](https://stackoverflow.com/questions/48549945/how-to-use-user-input-to-obtain-a-data-frame-from-my-environment-in-shiny/48550215#48550215) looks similar, maybe that can also help you. – Florian Feb 09 '18 at 14:08

1 Answers1

1

Well, thanks to florian's comment i think i might have found a solution my self. I'll present it here but leave the question open as there is probably far neater ways of doing it.

I rigged up the plots (that was created as lists by ggplot) into a list

plotList <- list(p_A1, p_A2, p_A3...)
tableList <- list(s_A1, s_A2, s_A3...)

I then used subset on my lookup table to get the matching id of the list to select the right plot and table.

output$thePlot <-renderPlot({

plotValue<-subset(letaLista, letaLista$Factor==input$Factor & 
letaLista$Variabel== input$Variabel & letaLista$rest_alla==input$DataSource)

plotList[as.integer(plotValue[1,4])]
})

output$theTable <-renderTable({ 

plotValue<-subset(letaLista, letaLista$Factor==input$Factor & 
letaLista$Variabel== input$Variabel & letaLista$rest_alla==input$DataSource)

skriva <- tableList[as.integer(plotValue[4])]
print(skriva)   

})
  • Hi Kristoffer, great that you were able to solve your own question. I think this is a good solution, I would have taken the same approach. One possible point of improvement: In the `subset` function ([docs](https://www.rdocumentation.org/packages/base/versions/3.4.3/topics/subset), you do not need to specify the dataframe everytime. i.e. `subset(letaLista, Factor==input$Factor)` should also work. – Florian Feb 09 '18 at 14:06