-1

If you run the R shiny script below, you get two boxes in an R shiny dashboard, The chart on the left displays a plot for all the traces or set of activities that occur in the eventlog data "patients_eventlog". "patients2" is a data in the script that explains each and every case appearing in column "a1", and corresponding activities basides in column "a2". My requirement is that when I click anywhere on a particular trace in the chart on left, I should get the relevant columns "a1","a2" and "a3" with the data having only and only those cases in which the activities in that trace are occurring. E.g. Let's say a trace in the chart on left has activites "Registration" and "Triage and Assessment", the by clicking on the trace, I want to see the cases with only and only those two activities. This just needs a minor tweak in the "output$sankey_table" server component. Please help and thanks.

## app.R ##
library(shiny)
library(shinydashboard)
library(bupaR)
library(lubridate)
library(dplyr)
library(xml2)
library(ggplot2)
library(ggthemes)
library(glue)
library(tibble)
library(miniUI)
library(tidyr)
library(shinyWidgets)
library(plotly)
library(DT)
library(splitstackshape)
library(scales)
patients$patient = as.character(patients$patient)
a1 = patients$patient
a2 = patients$handling
a3 = patients$time
a123 = data.frame(a1,a2,a3)
patients_eventlog = simple_eventlog(a123, case_id = "a1",activity_id = "a2", 
timestamp = "a3")
dta <- reactive({
tr <- data.frame(traces(patients_eventlog, output_traces = T, output_cases = 
F))
tr.df <- cSplit(tr, "trace", ",")
tr.df$af_percent <-
percent(tr.df$absolute_frequency/sum(tr.df$absolute_frequency))
pos <- c(1,4:ncol(tr.df))
tr.df <- tr.df[,..pos]
tr.df <- melt(tr.df, id.vars = c("trace_id","af_percent"))
tr.df
})
Purchase_Final <- reactive({
patients1 <- arrange(patients_eventlog, a1)
patients2 <- patients1 %>% arrange(a1, a3,a2)
patients2 %>%
group_by(a1) %>%
mutate(a3 = as.POSIXct(a3, format = "%m/%d/%Y %H:%M"),diff_in_sec = a3 - 
lag(a3)) %>% 
mutate(diff_in_sec = ifelse(is.na(diff_in_sec),0,diff_in_sec)) %>% 
mutate(diff_in_hours = as.numeric(diff_in_sec/3600)) %>% 
mutate(diff_in_days = as.numeric(diff_in_hours/24))
})
ui <- dashboardPage(
dashboardHeader(title = "Trace Chart"),
dashboardSidebar(
width = 0
),
dashboardBody(
box(title = "Trace Chart", status = "primary",height = "455" ,solidHeader = 
T,
    plotlyOutput("trace_plot"),style = "height:420px; overflow-y: 
scroll;overflow-x: scroll;"),

box( title = "Trace Summary", status = "primary", height = "455",solidHeader 
= T, 
     dataTableOutput("sankey_table"))
)
)
server <- function(input, output) 
{ 
output$trace_plot <- renderPlotly({


  mp1 = ggplot(data = dta(), aes(x = variable,y = trace_id, fill = value,
                               label = value,
                               text=paste("Variable:",variable,"<br> Trace 
                                          ID:",trace_id,"<br> 
 Value:",value,"<br> Actuals:",af_percent))) +
  geom_tile(colour = "white") +
  geom_text(colour = "white", fontface = "bold", size = 2) +
  scale_fill_discrete(na.value="transparent") +
  theme(legend.position="none") + labs(x = "Traces", y = "Activities")
  ggplotly(mp1, tooltip=c("text"), height = 1226, width = 1205)

 })
 output$sankey_table <- renderDataTable({
 d = event_data("plotly_click")
 d
 })

 }
 shinyApp(ui, server)

Addon Script for reference

app.R

library(shiny)
library(shinydashboard)
library(bupaR)
library(lubridate)
library(dplyr)
library(xml2)
library(ggplot2)
library(ggthemes)
library(glue)
library(tibble)
library(miniUI)
library(tidyr)
library(shinyWidgets)
library(plotly)
library(DT)
library(splitstackshape)
library(scales)
dta <- reactive({
tr <- data.frame(traces(patients, output_traces = T, output_cases = F))
tr.df <- cSplit(tr, "trace", ",")
tr.df$af_percent <-
percent(tr.df$absolute_frequency/sum(tr.df$absolute_frequency))
pos <- c(1,4:ncol(tr.df))
tr.df <- tr.df[,..pos]
tr.df <- melt(tr.df, id.vars = c("trace_id","af_percent"))
tr.df
})
patients10 <- reactive({
patients11 <- arrange(patients, patient)
patients12 <- patients11 %>% arrange(patient, time,handling_id)
patients12 %>%
group_by(patient) %>%
mutate(time = as.POSIXct(time, format = "%m/%d/%Y %H:%M"),diff_in_sec = time 
- lag(time)) %>% 
mutate(diff_in_sec = ifelse(is.na(diff_in_sec),0,diff_in_sec)) %>% 
mutate(diff_in_hours = as.numeric(diff_in_sec/3600)) %>% 
mutate(diff_in_days = as.numeric(diff_in_hours/24))
})
ui <- dashboardPage(
dashboardHeader(title = "Sankey Chart"),
dashboardSidebar(
width = 0
),
dashboardBody(
box(title = "Sankey Chart", status = "primary",height = "455" ,solidHeader = 
T,
    plotlyOutput("trace_plot")),

box( title = "Case Summary", status = "primary", height = "455",solidHeader 
= T, 
     dataTableOutput("trace_table"))
)
)
server <- function(input, output) 
{ 
output$trace_plot <- renderPlotly({
mp1 = ggplot(data = dta(), aes(x = variable,y = trace_id, fill = value,
                               label = value,
                               text=paste("Variable:",variable,"<br> Trace 
                                          ID:",trace_id,"<br> 
Value:",value,"<br> Actuals:",af_percent))) +
  geom_tile(colour = "white") +
  geom_text(colour = "white", fontface = "bold", size = 2) +
  scale_fill_discrete(na.value="transparent") +
  theme(legend.position="none") + labs(x = "Traces", y = "Activities")
ggplotly(mp1, tooltip=c("text"), height = 516, width = 605)

})
output$trace_table <- renderDataTable({
req(event_data("plotly_click"))
Values <- dta() %>% 
  filter(trace_id == event_data("plotly_click")[["y"]]) %>% 
  select(value)

valueText <- paste0(Values[[1]] %>% na.omit(),collapse = "")
agg <- aggregate(handling~patient, data = patients10(), FUN = function(y)
{paste0(unique(y),collapse = "")})

currentPatient <- agg$patient[agg$handling == valueText]

patients10_final <- patients10() %>%
  filter(patient %in% currentPatient)
datatable(patients10_final, options = list(paging = FALSE, searching = 
FALSE))
})
}
shinyApp(ui, server)

Trace Plot

Robert J
  • 79
  • 6
  • 1
    Please provide a [**minimal** reproducible example.](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – Claus Wilke Dec 23 '17 at 18:44
  • @ClausWilke, I have made life very simple for us now, Please check the script that runs perfectly under "Addon Script for reference". It gives you complete idea about my requirement. Now it's just about data, please help me as I have been struggling on it since ages. – Robert J Dec 24 '17 at 06:46
  • 1
    It's hard to believe this is a minimal example when you're loading in 28 packages. – Claus Wilke Dec 24 '17 at 06:52
  • @ClausWilke, See I get the minimal example thing, I'll be very clear here, The requirement is such that the details in a table depend on the on-click of the trace chart on the left. So putting the entire script is necessary. I regret but I don't know how can I ask such a requirement with less code. Kindly check this. – Robert J Dec 24 '17 at 06:55
  • @ClausWilke, I have reduced some packages for your clarity, Please check. – Robert J Dec 24 '17 at 06:58
  • @ClausWilke, I hope the added code gave some clarity on the requirement. Please let me know when you have an update. – Robert J Dec 24 '17 at 08:10
  • @ClausWilke, I have furthur reduced the script by removing unncessary script, now please check at help me here. – Robert J Dec 25 '17 at 05:04

1 Answers1

2

Since you have given such a huge example and its hard to decode each and every line in your code, I have removed some code to get the rows for your selected event.

Instead of event_data("plotly_click")[["y"]]) I am using the x as vent_data("plotly_click")$x and getting the trace_id by using paste0 function.

The part of the code that I have modified to get the rows is:

 output$trace_table <- renderDataTable({
      req(event_data("plotly_click"))
       trace = event_data("plotly_click")$x
      Values <- dta() %>% 
        filter(variable == paste0("trace_",trace))# %>% 
        #select(value)


      datatable(Values)
      # valueText <- paste0(Values[[1]] %>% na.omit(),collapse = "")
      # agg <- aggregate(handling~patient, data = patients10(), FUN = function(y)
      # {paste0(unique(y),collapse = "")})
      # 
      # currentPatient <- agg$patient[agg$handling == valueText]
      # 
      # patients10_final <- patients10() %>%
      #   filter(patient %in% currentPatient)
      # 
      # datatable(patients10_final, options = list(paging = FALSE, searching = 
      #                                              FALSE))
    })

EDIT: Here is the full code:

  library(shiny)
  library(shinydashboard)
  library(bupaR)
  library(lubridate)
  library(dplyr)
  library(xml2)
  library(ggplot2)
  library(ggthemes)
  library(glue)
  library(tibble)
  library(miniUI)
  library(tidyr)
  library(shinyWidgets)
  library(plotly)
  library(DT)
  library(splitstackshape)
  library(scales)
  dta <- reactive({
    tr <- data.frame(traces(patients, output_traces = T, output_cases = F))
    tr.df <- cSplit(tr, "trace", ",")
    tr.df$af_percent <-
      percent(tr.df$absolute_frequency/sum(tr.df$absolute_frequency))
    pos <- c(1,4:ncol(tr.df))
    tr.df <- tr.df[,..pos]
    tr.df <- melt(tr.df, id.vars = c("trace_id","af_percent"))
    tr.df
  })
  patients10 <- reactive({
    patients11 <- arrange(patients, patient)
    patients12 <- patients11 %>% arrange(patient, time,handling_id)
    patients12 %>%
      group_by(patient) %>%
      mutate(time = as.POSIXct(time, format = "%m/%d/%Y %H:%M"),diff_in_sec = time 
             - lag(time)) %>% 
      mutate(diff_in_sec = ifelse(is.na(diff_in_sec),0,diff_in_sec)) %>% 
      mutate(diff_in_hours = as.numeric(diff_in_sec/3600)) %>% 
      mutate(diff_in_days = as.numeric(diff_in_hours/24))
  })
  ui <- dashboardPage(
    dashboardHeader(title = "Sankey Chart"),
    dashboardSidebar(
      width = 0
    ),
    dashboardBody(
      box(title = "Sankey Chart", status = "primary",height = "455" ,solidHeader = 
            T,
          plotlyOutput("trace_plot")),

      box( title = "Case Summary", status = "primary", height = "455",solidHeader 
           = T, 
           dataTableOutput("trace_table"))
    )
  )
  server <- function(input, output) 
  { 
    output$trace_plot <- renderPlotly({
      mp1 = ggplot(data = dta(), aes(x = variable,y = trace_id, fill = value,
                                     label = value,
                                     text=paste("Variable:",variable,"<br> Trace 
                                                ID:",trace_id,"<br> 
                                                Value:",value,"<br> Actuals:",af_percent))) +
        geom_tile(colour = "white") +
        geom_text(colour = "white", fontface = "bold", size = 2) +
        scale_fill_discrete(na.value="transparent") +
        theme(legend.position="none") + labs(x = "Traces", y = "Activities")
      ggplotly(mp1, tooltip=c("text"), height = 516, width = 605)

    })
    output$trace_table <- renderDataTable({
      req(event_data("plotly_click"))
       trace = event_data("plotly_click")$x
      Values <- dta() %>% 
        filter(variable == paste0("trace_",trace))# %>% 
        #select(value)


      datatable(Values)
      # valueText <- paste0(Values[[1]] %>% na.omit(),collapse = "")
      # agg <- aggregate(handling~patient, data = patients10(), FUN = function(y)
      # {paste0(unique(y),collapse = "")})
      # 
      # currentPatient <- agg$patient[agg$handling == valueText]
      # 
      # patients10_final <- patients10() %>%
      #   filter(patient %in% currentPatient)
      # 
      # datatable(patients10_final, options = list(paging = FALSE, searching = 
      #                                              FALSE))
    })
  }
  shinyApp(ui, server)

Hope it helps!

SBista
  • 7,479
  • 1
  • 27
  • 58
  • thank you so much for replying , I am very very thankful, but can you please send me a consolidated script, I am facing issue running this. – Robert J Dec 25 '17 at 12:10
  • Hey, I tried this, small issue here, the code that you have modified is what I had provided for reference purpose. There is no issue with that code, I required your help in updating the script above "Addon Script for reference" whereby when I click any where on the trace of activities, I get to see the relevant cases with only and only those activities in the entire trace, not individually. E.g. trace with two activities should show both activities, similary for 3,4 Kindly check. – Robert J Dec 25 '17 at 12:33
  • You could use the same concept in your previous code. – SBista Dec 25 '17 at 13:00
  • See this is why I am chasing the community since ages, this code has been made such that it works on the "patients" data set well, when I make use of a real life eventlog, it is not giving good result, I need help regarding making the solution a little generalized to make it work on any data, There are other built in eventlogs like sepsis and bpic15_1 which are not giving proper result. – Robert J Dec 25 '17 at 13:41