简体   繁体   中英

Deploying dataTableOutput and plot in Shiny in R; "tidying" the dataTableOutput

I am developing a feature within a shiny app that shows a dataTableOutput and a plot associated with it. The plot displays the counts of unique ID's by group and date, while the table shows data associated with the time and date filtered. The column headings in the table are the dates within the data, which has been created using the pivot_wider function with tidyr . Here is some example code:-

Data

#relevant libraries
library(wakefield)#for generating the Status variable
library(dplyr)
library(stringi)
library(Pareto)
library(uuid)
library(ggplot2)
library(data.table)
library(shiny)
library(DT)


#mock data creation
set.seed(1)
#data<-data.frame()
Date<-seq(as.Date("2015-01-01"), as.Date("2015-12-31"), by = "1 day")
Date<-sample(rep(Date,each=10),replace = T)

event<-r_sample_factor(x = c("Wrestling", "Drama", 
                                    "Information", "Football", "Rugby", "Movie", "Music", "News"), n=length(Date))

channel<-r_sample_factor(x = c("Channel 1", "Channel 2", "Channel 3", "Channel 4"), n=length(Date))

Hour<-r_sample_factor(x = c(0:23), n=length(Date))

Group<-r_sample_factor(x = c("A","B","C","D","E"), n=length(Date))

#creating user ID

set.seed(1)

n_users <- 100
n_rows <- 3650

relative_probs <- rPareto(n = n_users, t = 1, alpha = 0.3, truncation = 500) 
unique_ids <- UUIDgenerate(n = n_users)

AnonID <- sample(unique_ids, size = n_rows, prob = relative_probs, replace = TRUE)


data<-data.frame(AnonID,Group,Date,Hour,channel,event)
data$Hour<-as.numeric(data$Hour)
head(data)

Shiny code


#ui================================
ui<-fluidPage(
  titlePanel("Example panel"),
  tabsetPanel(
    tabPanel("example text",
             sidebarPanel(width = 4,
                          dateRangeInput("daterange","Select dates", format = "yyyy-mm-dd",
                                         start = min("2015-01-01"),
                                         end = max("2015-01-10")),
                          numericInput("hourmin", "Select mininum hour",10,0,23),
                          numericInput("hourmax", "Select maximum hour", 22,0,23),
                          pickerInput("channel", "Select channel",
                                      choices = unique(channel), options = list('actions-box'=T,'live-search'=T),multiple = T)),#end of sidebarPanel
             mainPanel(
               column(width = 10, plotOutput("barplot", width = "100%")),
                      column(width = 8, dataTableOutput("table"))
             )#end of mainPanel
                          
             )
             )#end of tabPanel
  )#end of tabsetPanel
)#end of fluidPage


#server===========================================

server<-function(input,output,session){

  
 rv <- reactiveVal(NULL)  
  
  observe({
    
    rv(data)
  
    output$table<-renderDataTable({
      rv()%>%
      arrange(desc(Date))%>%
      filter(Date>=input$daterange[1] & Date<=input$daterange[2])%>%
      filter(Hour>=input$hourmin & Hour<=input$hourmax)%>%
      filter(channel %in% input$channel)%>%  
      group_by(channel,Hour,Date)%>%
      arrange(Hour,Date)%>%
      summarise(Programme=event, .groups = 'drop')%>%
      mutate(rn=rowid(Hour,Date))%>%
      pivot_wider(names_from = Date,values_from = Programme)%>%
      select(-rn)
    })
    
    output$barplot<-renderPlot({
      
      rv()%>%
        filter(Date>=input$daterange[1] & Date<=input$daterange[2])%>%
        filter(Hour>=input$hourmin & Hour<=input$hourmax)%>%
        filter(channel %in% input$channel)%>%
        group_by(Date,Group)%>%
        summarise(UniqueID=n_distinct(AnonID))%>%
        ggplot()+
        geom_bar(aes(x=Date,y=UniqueID, fill=Group), stat = "identity", position = "dodge")
        
      
    })
    
    })#end of observe
  }

shinyApp(ui,server)

Here is the output:-

在此处输入图片说明

You can see the data table, I have created a sort of "TV guide", showing the dates and hours of the programmes. However, I think it is a bit of an eyesore with the missing fields. Rather than populating them with other text, I was wondering if there were a better way to display the table like this, so that there is little/none empty spaces and that it makes it more concise?

Secondly, I was wondering how I could make it interactive. I would like to be able to click on the cell/row of the data table, with the result of reactively updating the plot with new counts of UniqueID for that given hour and date? Would this be easy to implement and if so can someone show me how? thank you :)

You should consider asking two separate questions. For the first part, you could display the hour and event together, this way you can display one row for each channel. Then you can provide the key at the bottom of the table as only first 3 letters are displayed for each event. Try this

output$table<-renderDT({
      rv()%>%
        arrange(desc(Date))%>%
        filter(Date>=input$daterange[1] & Date<=input$daterange[2])%>%
        filter(Hour>=input$hourmin & Hour<=input$hourmax)%>%
        filter(channel %in% input$channel)%>%  
        group_by(channel,Date)%>%
        arrange(Date)%>%
        summarise(Programme=paste0(Hour,":",substr(event,1,3)), .groups = 'drop')%>%
        #mutate(rn=rowid(Date))%>%
        pivot_wider(names_from = Date,values_from = Programme) # %>%
        #select(-rn)
    })

输出

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM