在 Shiny 中编辑数据:`警告:错误 [:维数不正确`
Editing data in Shiny: `Warning: Error in [: incorrect number of dimensions`
我的目标是构建一个闪亮的应用程序,我可以在其中上传两个数据帧,该应用程序将:
- 自动突出显示两个数据帧之间的差异
- 允许直接编辑数据框
- 请允许我下载新编辑的数据框
编辑 2022 年 6 月 1 日
我已经使用 datatable
创建了一个有效的 reprex,它将突出显示不一致的单元格并且几乎允许编辑功能,但是只要我进行任何编辑,下面的代码就会生成一条错误消息:Warning: Error in [: incorrect number of dimensions
.对解决此错误的任何建议表示赞赏。
我以前尝试用 gt
解决这个问题,但我认为 gt
不适合编辑功能。 Text from pre-edit question.
代表
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)
我解决了我的问题,下面有一个功能正常的 reprex,允许编辑、突出显示和下载。我认为核心问题是确保显示突出显示的数据表对象,但数据表 (val$x$x$data
) 的数据框元素被专门编辑和下载(而不是整个数据表本身)。
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::DTOutput("print"))
)
),
)
server <- function(input, output, session) {
df1 <- reactive({ dat1
# inFile <- input$file1
# if (is.null(input$file1))
# return(NULL)
# readxl::read_excel(inFile$datapath)
})
df2 <- reactive({ dat2
# inFile <- input$file2
# if (is.null(input$file2))
# return(NULL)
# readxl::read_excel(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 <- DT::renderDT({ vals$x })
output$contents <- DT::renderDataTable(vals$x)
proxy <- dataTableProxy("contents")
observeEvent(input$print_cell_edit, {
info = input$print_cell_edit
str(info)
i = info$row
j = info$col + 1
v = info$value
vals$x$x$data[i, j] <<- DT:::coerceValue(v, vals$x$x$data[i, j])
replaceData(proxy, vals$x$x$data, resetPaging = FALSE, rownames = FALSE)
})
output$download <- downloadHandler("example.csv",
content = function(file){
write.csv(vals$x$x$data, file, row.names = F)
},
contentType = "text/csv")
}
shinyApp(ui = ui, server = server)
我的目标是构建一个闪亮的应用程序,我可以在其中上传两个数据帧,该应用程序将:
- 自动突出显示两个数据帧之间的差异
- 允许直接编辑数据框
- 请允许我下载新编辑的数据框
编辑 2022 年 6 月 1 日
我已经使用 datatable
创建了一个有效的 reprex,它将突出显示不一致的单元格并且几乎允许编辑功能,但是只要我进行任何编辑,下面的代码就会生成一条错误消息:Warning: Error in [: incorrect number of dimensions
.对解决此错误的任何建议表示赞赏。
我以前尝试用 gt
解决这个问题,但我认为 gt
不适合编辑功能。 Text from pre-edit question.
代表
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)
我解决了我的问题,下面有一个功能正常的 reprex,允许编辑、突出显示和下载。我认为核心问题是确保显示突出显示的数据表对象,但数据表 (val$x$x$data
) 的数据框元素被专门编辑和下载(而不是整个数据表本身)。
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::DTOutput("print"))
)
),
)
server <- function(input, output, session) {
df1 <- reactive({ dat1
# inFile <- input$file1
# if (is.null(input$file1))
# return(NULL)
# readxl::read_excel(inFile$datapath)
})
df2 <- reactive({ dat2
# inFile <- input$file2
# if (is.null(input$file2))
# return(NULL)
# readxl::read_excel(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 <- DT::renderDT({ vals$x })
output$contents <- DT::renderDataTable(vals$x)
proxy <- dataTableProxy("contents")
observeEvent(input$print_cell_edit, {
info = input$print_cell_edit
str(info)
i = info$row
j = info$col + 1
v = info$value
vals$x$x$data[i, j] <<- DT:::coerceValue(v, vals$x$x$data[i, j])
replaceData(proxy, vals$x$x$data, resetPaging = FALSE, rownames = FALSE)
})
output$download <- downloadHandler("example.csv",
content = function(file){
write.csv(vals$x$x$data, file, row.names = F)
},
contentType = "text/csv")
}
shinyApp(ui = ui, server = server)