/R/artefact_viewer.R

https://github.com/craddm/eegUtils · R · 169 lines · 131 code · 24 blank · 14 comment · 4 complexity · f44d1c8a990165c982228d8b54656922 MD5 · raw file

  1. #' Artefact browser
  2. #'
  3. #' An interactive Shiny app that allows exploration of channel and epoch
  4. #' statistics.
  5. #'
  6. #' @author Matt Craddock \email{matt@@mattcraddock.com}
  7. #' @import shiny
  8. #' @importFrom tidyr gather spread
  9. #' @import ggplot2
  10. #' @importFrom plotly plot_ly renderPlotly event_data
  11. #' @param data Object to be explored.
  12. #' @return None.
  13. #' @export
  14. view_artefacts <- function(data) {
  15. chan_dat <- channel_stats(data)
  16. scale_chans <- dplyr::mutate_if(chan_dat,
  17. is.numeric,
  18. ~(. - mean(.)) / sd(.))
  19. epoch_dat <- epoch_stats(data)
  20. epoch_dat <- tidyr::pivot_longer(epoch_dat,
  21. cols = channel_names(data),
  22. names_to = "electrode",
  23. values_to = "value")
  24. epoch_dat <- tidyr::pivot_wider(epoch_dat,
  25. id_cols = c(epoch, electrode),
  26. names_from = measure,
  27. values_from = value)
  28. ui <-
  29. navbarPage("Artefact checks",
  30. tabPanel("Channel stats",
  31. sidebarLayout(
  32. sidebarPanel(selectInput("chan_meas",
  33. "Display measures",
  34. choices = c("means",
  35. "sds",
  36. "variance",
  37. "kurtosis",
  38. "minmax")
  39. ),
  40. checkboxInput("std_meas",
  41. "Standardize?"),
  42. width = 3),
  43. mainPanel(
  44. plotly::plotlyOutput("chan_plot"),
  45. #channelPlotly(chan_dat),
  46. fluidRow(
  47. column(6,
  48. plotly::plotlyOutput("erpplot")),
  49. column(6,
  50. plotly::plotlyOutput("erpimage"))),
  51. ),
  52. )),
  53. tabPanel("Epoch stats",
  54. epochPlotly(epoch_dat))
  55. )
  56. server <- function(input, output) {
  57. plot_data <- reactive({
  58. if (input$std_meas) {
  59. scale_chans
  60. } else {
  61. chan_dat
  62. }
  63. })
  64. output$chan_plot <- plotly::renderPlotly({
  65. ylab <- switch(
  66. input$chan_meas,
  67. means = "Mean",
  68. variance = "Var",
  69. sds = "Std. dev.",
  70. kurtosis = "Kurtosis",
  71. minmax = "Max - min"
  72. )
  73. plotly::plot_ly(plot_data(),
  74. x = ~electrode,
  75. y = ~get(input$chan_meas)) %>%
  76. plotly::add_markers() %>%
  77. plotly::layout(yaxis = list(title = ylab))
  78. })
  79. output$erpplot <- plotly::renderPlotly({
  80. s <- plotly::event_data("plotly_click")
  81. if (length(s)) {
  82. plot_timecourse(data,
  83. electrode = s[["x"]]) +
  84. labs(y = "amplitude")
  85. }
  86. })
  87. output$erpimage <- plotly::renderPlotly({
  88. s <- plotly::event_data("plotly_click")
  89. if (length(s)) {
  90. erp_image(data,
  91. electrode = s[["x"]])
  92. }
  93. })
  94. output$plotly_emeans <- plotly::renderPlotly({
  95. plotly::plot_ly(epoch_dat,
  96. y = ~electrode,
  97. x = ~epoch,
  98. z = ~max,
  99. type = "heatmap") %>%
  100. plotly::layout(title = "Max")
  101. })
  102. output$plotly_evars <- plotly::renderPlotly({
  103. plotly::plot_ly(epoch_dat,
  104. x = ~epoch,
  105. y = ~electrode,
  106. z = ~variance,
  107. type = "heatmap") %>%
  108. plotly::layout(title = "Variance")
  109. })
  110. output$plotly_kurt <- plotly::renderPlotly({
  111. plotly::plot_ly(epoch_dat,
  112. x = ~epoch,
  113. y = ~electrode,
  114. z = ~kurtosis,
  115. type = "heatmap") %>%
  116. plotly::layout(title = "Kurtosis")
  117. })
  118. output$plotly_minmax <- plotly::renderPlotly({
  119. plotly::plot_ly(epoch_dat,
  120. x = ~epoch,
  121. y = ~electrode,
  122. z = ~minmax,
  123. type = "heatmap") %>%
  124. plotly::layout(title = "Max-min")
  125. })
  126. }
  127. shiny::shinyApp(ui,
  128. server)
  129. }
  130. epochPlotly <- function(id,
  131. label = "Plotly channels") {
  132. ns <- shiny::NS(id)
  133. tagList(
  134. fluidRow(
  135. plotly::plotlyOutput("plotly_emeans",
  136. height = 250),
  137. plotly::plotlyOutput("plotly_evars",
  138. height = 250),
  139. plotly::plotlyOutput("plotly_kurt",
  140. height = 250),
  141. plotly::plotlyOutput("plotly_minmax",
  142. height = 250)
  143. )
  144. )
  145. }