gpt4 book ai didi

r - 使用因子变量的下拉选择来编辑Shiny中的数据表

转载 作者:行者123 更新时间:2023-12-03 16:23:43 24 4
gpt4 key购买 nike

我正在尝试创建一个Shiny应用程序,该应用程序允许用户编辑数据表,从而保存所做的编辑。这是一个最小的示例:

library(shiny)
library(DT)

ui <- fluidPage(
DT::DTOutput('df')
)

server <- function(session, input, output){
df <- data.frame(x = factor(c("A", "B", "C"), levels = c("A", "B", "C")))
output$df <- DT::renderDT(df,
editable = T)

proxy <- dataTableProxy("df")

observeEvent(input$df_cell_edit, {
info <- input$df_cell_edit
str(info)
i <- info$row
j <- info$col
v <- info$value
df[i, j] <<- DT:::coerceValue(v, df[i, j])
replaceData(proxy, df, resetPaging = FALSE)

})
}

shinyApp(ui, server)

这使我可以在线编辑 x的值,但是由于 x是一个因素,我想限制用户能够输入的值。理想情况下,我希望使用下拉菜单来完成此操作。使用DT::datatable和Shiny可以实现此功能吗?

注意:我知道 rhandsontable包,但是如果可能的话,我更愿意使用DT。

最佳答案

正如我在评论中所说,您可以使用JS库 cellEdit 做到这一点。
这是使用JS库 contextMenu (一个jQuery插件)的另一种方法。

library(shiny)
library(DT)

callback <- c(
"var id = $(table.table().node()).closest('.datatables').attr('id');",
"$.contextMenu({",
" selector: '#' + id + ' td.factor input[type=text]',",
" trigger: 'hover',",
" build: function($trigger, e){",
" var colindex = table.cell($trigger.parent()[0]).index().column;",
" var coldata = table.column(colindex).data().unique();",
" var options = coldata.reduce(function(result, item, index, array){",
" result[index] = item;",
" return result;",
" }, {});",
" return {",
" autoHide: true,",
" items: {",
" dropdown: {",
" name: 'Edit',",
" type: 'select',",
" options: options,",
" selected: 0",
" }",
" },",
" events: {",
" show: function(opts){",
" opts.$trigger.off('blur');",
" },",
" hide: function(opts){",
" var $this = this;",
" var data = $.contextMenu.getInputValues(opts, $this.data());",
" var $input = opts.$trigger;",
" $input.val(options[data.dropdown]);",
" $input.trigger('change');",
" }",
" }",
" };",
" }",
"});"
)
ui <- fluidPage(
tags$head(
tags$link(
rel = "stylesheet",
href = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.css"
),
tags$script(
src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.js"
)
),
DTOutput("dtable")
)

server <- function(input, output){
output[["dtable"]] <- renderDT({
datatable(
iris, editable = "cell", callback = JS(callback),
options = list(
columnDefs = list(
list(
targets = 5, className = "factor"
)
)
)
)
}, server = FALSE)
}

shinyApp(ui, server)
enter image description here
编辑
这是一个改进。在上一个应用程序中,下拉选项设置为该列的唯一值。使用下面的应用程序,您可以设置所需的下拉选项。
library(shiny)
library(DT)

callback <- c(
"var id = $(table.table().node()).closest('.datatables').attr('id');",
"$.contextMenu({",
" selector: '#' + id + ' td.factor input[type=text]',",
" trigger: 'hover',",
" build: function($trigger, e){",
" var levels = $trigger.parent().data('levels');",
" if(levels === undefined){",
" var colindex = table.cell($trigger.parent()[0]).index().column;",
" levels = table.column(colindex).data().unique();",
" }",
" var options = levels.reduce(function(result, item, index, array){",
" result[index] = item;",
" return result;",
" }, {});",
" return {",
" autoHide: true,",
" items: {",
" dropdown: {",
" name: 'Edit',",
" type: 'select',",
" options: options,",
" selected: 0",
" }",
" },",
" events: {",
" show: function(opts){",
" opts.$trigger.off('blur');",
" },",
" hide: function(opts){",
" var $this = this;",
" var data = $.contextMenu.getInputValues(opts, $this.data());",
" var $input = opts.$trigger;",
" $input.val(options[data.dropdown]);",
" $input.trigger('change');",
" }",
" }",
" };",
" }",
"});"
)

createdCell <- function(levels){
if(missing(levels)){
return("function(td, cellData, rowData, rowIndex, colIndex){}")
}
quotedLevels <- toString(sprintf("\"%s\"", levels))
c(
"function(td, cellData, rowData, rowIndex, colIndex){",
sprintf(" $(td).attr('data-levels', '[%s]');", quotedLevels),
"}"
)
}

ui <- fluidPage(
tags$head(
tags$link(
rel = "stylesheet",
href = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.css"
),
tags$script(
src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.js"
)
),
DTOutput("dtable")
)

server <- function(input, output){
output[["dtable"]] <- renderDT({
datatable(
iris, editable = "cell", callback = JS(callback),
options = list(
columnDefs = list(
list(
targets = 5,
className = "factor",
createdCell = JS(createdCell(c(levels(iris$Species), "another level")))
)
)
)
)
}, server = FALSE)
}

shinyApp(ui, server)
如果要使用列的唯一值,请将选项 createdCell设置为 JS(createdCell()),或者干脆不设置此选项。

关于r - 使用因子变量的下拉选择来编辑Shiny中的数据表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52593539/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com