Shiny R: Search, edit, and export within reactive dataframe using brushedPoints
I am new to Shiny and have hacked away at this problem and am very close to solution (at least I think I am), but need a bit of help to get me over the finish line.
I have provided an example input data frame (data1) and the desired result (result) below to show where I would like to end up.
My actual data set includes ~1000 samples with each sample having approximately 150 rows of x-y coordinate data that I need to plot, examine, add information to, and then extract for further analyses.
As of now, I have setup a Shiny App that allows me to use radio buttons to select specific samples using “site” and “sample” identifiers and then plot the selected data. I also included a download button for the modified data table.
The App uses the brushedPoints function to allow me to select portions of the plot and then display the selected points in two tables: i) a data table that is editable and ii) a second data table that shows the edits in the data table that will be exported. The second data table might not be necessary, but it shows me how/if the edits are being incorporated into the data table that will be exported.
Currently, when I highlight data points and type in the “move” or “stay” columns in the top table, the edits fail to show up in the bottom table or in the downloaded csv file.
I identified the area of the code that appears to be the problem, but am unsure of the solution.
All recommendations are welcome.
Thanks for your time...
rm(list=ls())
# Loads the two packages need to run the code below
library(DT)
library(dplyr)
library(tidyr)
library(ggplot2)
library(shiny)
# data
site <- c('a','a','a','a','a','b','b','b','b','b')
sample <- c("1a", "1a", "1a", "1a", "1a","2b", "2b", "2b","2b", "2b")
x <- c(1, 2, 3, 4, 5, 6, 7, 8 , 9, 10)
y <- c(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
move <- c('na', 'na', 'na', 'na', 'na', 'na', 'na', 'na', 'na', 'na')
stay <- c('na', 'na', 'na', 'na', 'na', 'na', 'na', 'na', 'na', 'na')
sub <- data.frame(site, sample, x, y, move, stay)
# example result
site <- c('a','a','a','a','a','b','b','b','b','b')
sample <- c("1a", "1a", "1a", "1a", "1a","2b", "2b", "2b","2b", "2b")
x <- c(1, 2, 3, 4, 5, 6, 7, 8 , 9, 10)
y <- c(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
move <- c('na', 'yes', 'na', 'no', 'na', 'down', 'na', 'up', 'na', 'na')
stay <- c(1, 20, 'na', 'na', 50, 'na', 69, 'na', 'na', 77)
result <- data.frame(site, sample, x, y, move, stay)
#================================================================================================
ui <- fluidPage(
sidebarPanel(
downloadButton("download","Download"),
radioButtons("site", "Site",
choices = unique(sub$site)),
radioButtons("sample", "Sample",
choices = unique(sub$sample))),
mainPanel(
plotOutput("plot1", brush = "plot_brush"),
DTOutput("plot_brushed_points"),
verbatimTextOutput("acutal_data")
)
)
server <- function(input, output, session) {
# Change second radio button options based on first radio button
observeEvent(input$site,{
Choices = unique(sub$sample[sub$site == input$site])
updateRadioButtons(session, "sample", choices = Choices)
})
# Make data set reactive values
sub_react = reactiveValues(data = sub)
# Get data for plot
reactive_data <- reactive({
selected_sample = input$sample
filter(sub_react$data, sample == selected_sample)
})
# Make plot
output$plot1 <- renderPlot({
our_data <- reactive_data()
ggplot(our_data, aes(x = x, y = y)) +
geom_line(aes(), color = 'black') +
geom_point(aes(size = 5))+
geom_point(shape = 1 ,size = 5, colour = "black") +
xlim(0, 10) +
ylim(0, 100)
})
# Display rows of data highlighted in plot
dat <- reactive({
our_data <- reactive_data()
brushedPoints(our_data, input$plot_brush, xvar = "x", yvar = "y", allRows = FALSE)
})
# Render highlighted data in plot
output$plot_brushed_points = renderDT(dat(), selection = 'none', editable = TRUE)
# Show actual data frame to check edits are correct
output$acutal_data <- renderPrint({dat()})
# Transfer edits from top table to bottom table
##############################################
## I suspect this is where the problem lies ##
##############################################
proxy = dataTableProxy('plot_brushed_points')
observeEvent(input$plot_brushed_points_cell_edit, {
info = input$plot_brushed_points_cell_edit
str(info)
i = info$row
j = info$col
v = info$value
sub_react$data[i, j] <- isolate(coerceValue(v, sub_react$data[i, j]))
replaceData(proxy, sub_react$data, resetPaging = FALSE)
})
# Download modified data table as a csv file
output$download <- downloadHandler(
filename = function() {
paste0("Modified_data.csv")
},
content = function(con) {
write.csv(sub_react$data, con, row.names = FALSE, na = "")
}
)
}
shinyApp(ui, server)