r - 让用户在 R Shiny 中编辑数据表变量名称
问题描述
我正在构建一个 R Shiny 应用程序,用户在其中选择数据表中的列,然后该应用程序返回所选变量的列表。我希望用户能够更改应用程序中变量/列的名称。
我使用 DT 制作了这个交互式表格。我从 Stéphane Laurent 在这篇文章中的回答中获得了更改列标题的代码。
虽然列选择和可编辑列名在 DT 表中都可以正常工作,但问题是更改变量名只会编辑显示的表,而原始数据框仍保留其原始列名。我希望当用户在应用程序中编辑变量名称时,它会更改实际数据框中的变量名称。我如何实现这一目标?
每次用户更改列名时,我都在考虑使用 observeEvent() 来更改列名,但是由于 Stéphane Laurent 给出的方法使用 JS,我不太确定该怎么做。
(此处应用程序的屏幕截图;我更改了 2 个选定列的列名,但原始数据框尚未更新。)
library(shiny)
library(DT)
getlist <- function(df, colnums){
data <- df
if(length(colnums)==1){
column_names <- colnames(data)[colnums]
} else{
selected_data <- data[,colnums]
column_names <- colnames(selected_data)
}
return(column_names)
}
callback <- c(
"table.on('dblclick.dt', 'thead th', function(e) {",
" var $th = $(this);",
" var index = $th.index();",
" var colname = $th.text(), newcolname = colname;",
" var $input = $('<input type=\"text\">')",
" $input.val(colname);",
" $th.empty().append($input);",
" $input.on('change', function(){",
" newcolname = $input.val();",
" if(newcolname != colname){",
" $(table.column(index).header()).text(newcolname);",
" }",
" $input.remove();",
" }).on('blur', function(){",
" $(table.column(index).header()).text(newcolname);",
" $input.remove();",
" });",
"});"
)
ui <- fluidPage(
DTOutput("table"),
textOutput('preview'),
tableOutput('table2')
)
server <- function(input, output){
data <- reactiveVal(iris)
output[["table"]] <- renderDT({
datatable(data(), selection = list(target = 'column'), options= list(ordering = FALSE, pageLength = 25), callback = JS(callback))
})
#selected columns of the tables
vlist <- reactive(c(getlist(data(),input$table_columns_selected)))
#display list of selected variables
output$preview <- renderText(paste(c('Selected variables :', vlist()), collapse=' '))
output$table2 <- renderTable({data()})
}
shinyApp(ui, server)
解决方案
您可以使用Shiny.setInputValue()
从 JS 向 Shiny 发送消息并生成输入值。我使用它来将新旧列名从 JS 函数发送到input$change_colname
. 然后您可以使用它observeEvent
来更新您的数据。在您的情况下,我将使用不同的对象来渲染table
and table2
,因为现在table
在列名更改后随着基础data()
的更新而重新渲染:
library(shiny)
library(DT)
getlist <- function(df, colnums){
data <- df
if(length(colnums)==1){
column_names <- colnames(data)[colnums]
} else{
selected_data <- data[,colnums]
column_names <- colnames(selected_data)
}
return(column_names)
}
callback <- c(
"table.on('dblclick.dt', 'thead th', function(e) {",
" var $th = $(this);",
" var index = $th.index();",
" var colname = $th.text(), newcolname = colname;",
" var $input = $('<input type=\"text\">')",
" $input.val(colname);",
" $th.empty().append($input);",
" $input.on('change', function(){",
" newcolname = $input.val();",
" if(newcolname != colname){",
" $(table.column(index).header()).text(newcolname);",
" Shiny.setInputValue('change_colname', [colname, newcolname]);",
" }",
" $input.remove();",
" }).on('blur', function(){",
" $(table.column(index).header()).text(newcolname);",
" $input.remove();",
" });",
"});"
)
ui <- fluidPage(
DTOutput("table"),
textOutput('preview'),
tableOutput('table2')
)
server <- function(input, output){
data <- reactiveVal(iris)
vlist <- reactiveVal()
output[["table"]] <- renderDT({
datatable(data(), selection = list(target = 'column'), options= list(ordering = FALSE, pageLength = 25), callback = JS(callback))
})
#selected columns of the tables
observeEvent(input$table_columns_selected, {
vlist(getlist(data(),input$table_columns_selected))
})
# update column names
observeEvent(input$change_colname, {
old_colnames <- vlist()
old_colnames[old_colnames == input$change_colname[1]] <- input$change_colname[2]
vlist(old_colnames)
# update the data
old_data <- data()
colnames(old_data)[colnames(old_data) == input$change_colname[1]] <-
input$change_colname[2]
data(old_data)
})
#display list of selected variables
output$preview <- renderText(paste(c('Selected variables :', vlist()), collapse=' '))
output$table2 <- renderTable({data()})
output$changed_var <- renderPrint({input$change_colname})
}
shinyApp(ui, server)
推荐阅读
- sql - SQL - 如何识别给定数据中的 1 小时时间段孤岛?
- ios - Swift 中的非英文字符给出:致命错误:在展开可选值时意外发现 nil
- pytorch - Pytorch:如何在 OrderedDict 中将 requires_grad 更改为 true
- r - 过滤数据集以不按列显示顶行
- python - 如何在抓取数据时防止 IP 阻塞
- elasticsearch - 检查 logstash fieldName 中的模式
- python - 根据掩码将numpy数组替换为另一个数组
- sql - 带有 MAXDATE 错误消息 208,无效对象名称的子查询
- amazon-web-services - 如何使用 terraform 为 AWS 网络防火墙添加到 VPC 网关端点的路由
- reactjs - NextJs:在 React useEffect Hook 内使用变量调用 setInterval