Hello, my goal is to build a Shiny app where I can upload two dataframes and the app will:
- Automatically highlight discrepancies between the two dataframes
- Allow direct editing to the dataframe
- Allow me to download the newly-edited dataframe
I have created a working reprex using datatable
that will highlight discrepant cells and almost allows for editing capability, but the below code generates an error message as soon as I make any edits: Warning: Error in [: incorrect number of dimensions
. Any advice on resolving this error is appreciated. I previously tried solving this issue with gt
, but I don't believe gt
is suitable for editing capability.
library(shiny)
library(shinythemes)
library(data.table)
library(DT)
library(tidyverse)
dat1 <- data.frame(
emp_id = c(1:5),
emp_name = c("Rick","Dan","Michelle","Ryan","Gary"),
salary = c(623.3,515.2,611.0,735.0,844.25))
dat2 <- data.frame(
emp_id = c(1:5),
emp_name = c("Rick","Dan","Michelle","Ryan","Gary"),
salary = c(623.3,515.2,611.0,729.0,843.25))
ui <- navbarPage("This is my Shiny app.",
theme = shinytheme("flatly"),
tabPanel("Upload",
titlePanel("Upload your datafiles"),
sidebarLayout(
sidebarPanel(
## File 1
fileInput('file1', 'Data Entry #1',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
tags$hr(),
## File 2
fileInput('file2', 'Data Entry #2',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
tags$hr(),
downloadButton("download")
),
mainPanel(
DT::dataTableOutput("contents"),
verbatimTextOutput("print"))
)
),
)
server <- function(input, output, session) {
df1 <- reactive({ dat1
# inFile <- input$file1
# if (is.null(input$file1))
# return(NULL)
# read.csv(inFile$datapath)
})
df2 <- reactive({ dat2
# inFile <- input$file2
# if (is.null(input$file2))
# return(NULL)
# read.csv(inFile$datapath)
})
vals <- reactiveValues(x = NULL)
observe({
req(df1())
req(df2())
tbl_diffs <- which(df1() != df2(), arr.ind = TRUE)
tbl_compare <- df2() %>% DT::datatable(selection = 'none', rownames = FALSE, edit = TRUE)
for (i in seq_len(nrow(tbl_diffs))) {
tbl_compare <- tbl_compare %>%
formatStyle(
columns = tbl_diffs[[i, "col"]],
backgroundColor = styleRow(tbl_diffs[[i, "row"]], c('yellow')))
}
vals$x <- tbl_compare
})
output$print <- renderPrint({ vals$x })
output$contents <- DT::renderDataTable(vals$x)
proxy <- dataTableProxy("contents")
observeEvent(input$contents_cell_edit, {
info = input$contents_cell_edit
str(info)
i = info$row
j = info$col + 1
v = info$value
vals$x[i, j] <<- DT:::coerceValue(v, vals$x[i, j])
replaceData(proxy, vals$x, resetPaging = FALSE, rownames = FALSE)
})
output$download <- downloadHandler("example.csv",
content = function(file){
write.csv(vals$x, file, row.names = F)
},
contentType = "text/csv")
}
shinyApp(ui = ui, server = server)