如何在 R shiny 中替换数据表的值

How can values of a datatable be replaced in R shiny

我正在创建一个简单的 R shiny 应用程序,用户可以在其中上传一个 .CSV 文件并在主面板中呈现数据 table,并在 'select column' 中自动突出显示列名称部分。

我要找的是:

如何替换值? (从旧值到新值)。例如,我应该如何通过引用 'select column' 中的列名将 'range' 列中的值 100 修改为 500?

注意:我还包括了一个 textInput 框来提及旧值和新值。

csv 数据

ID  Type  Category    Range
21  A1     B1          100
22  C1     D1          200
23  E1     F1          300

app.R

library(shiny)
library(shinydashboard)
library(reshape2)
library(DT)



ui <- dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(
      fileInput("file1","Uplaod Data",buttonLabel = "Browse..",placeholder = "No file Selected"),
      checkboxInput("header", "Header", TRUE),
      #actionButton("Splitcolumn", "SplitColumn"),
      selectInput(inputId='selectcolumn', label='select column', ''),
      #actionButton("deleteRows", "Delete Rows"),
      textInput('oldvalue', label='Oldvalue'),
      textInput('newvalue', label='New value to replace')
    ),
    mainPanel(
      DTOutput("table1"),
   
    
  ),
  
  )
)

server <- function(session, input, output) {
  rv <- reactiveValues(data = NULL)
  
  observeEvent(input$file1, {
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    
    req(file)
    
    validate(need(ext == "csv", "Please upload a csv file"))
    
    rv$data <- read.csv(file$datapath, header = input$header)
    
    updateSelectInput(session, 'selectcolumn', 'select column', names(rv$data))
    
  })
  
  observeEvent(input$Splitcolumn, {
    rv$data <- splitColumn(rv$data, input$selectcolumn)
  })
  
  observeEvent(input$deleteRows,{
    if (!is.null(input$table1_rows_selected)) {
      rv$data <- rv$data[-as.numeric(input$table1_rows_selected),]
    }
  })
  
  output$table1 <- renderDT({
    rv$data
  })
}

shinyApp(ui, server)

下面的简化代码可以满足您的需求:

library(shiny)
library(DT)
library(dplyr)

ui <- fluidPage(
   sidebarLayout(
      sidebarPanel(
         selectInput("col", "Column to search:", names(mtcars), names(mtcars)[1]),
         textInput("old", "Replace:"),
         textInput("new", "By:"),
         actionButton("replace", "Replace!"),
      ),
      mainPanel(
         DTOutput("table1")
      )
   )
)

server <- function(input, output, session) {
   my_data <- reactiveVal(mtcars)
   
   observeEvent(input$replace, {
      req(input$col)
      dat <- my_data()
      traf <- if (is.numeric(dat[[input$col]])) as.numeric else identity
      my_data(dat %>%
                 mutate(!!rlang::sym(input$col) := 
                           replace(!!rlang::sym(input$col),
                                   as.character(!!rlang::sym(input$col)) == input$old,
                                   input$new) %>% 
                           traf()))
   })
   
   output$table1 <- renderDT(
      my_data()
   )
}

shinyApp(ui, server)

部分备注按顺序:

  • 我添加了一个 actionButton 以允许触发替换
  • 我删除了上传位,b/c这对手头的问题来说不是必需的(在最终的应用程序中,只需将上传的数据分配给my_data
  • 我使用 replace 进行实际替换(还有其他选项)。因此,我首先将数据转换为 character 向量。如果之前是数字,我重新转换值。还没有考虑其他数据类型,所以一些想法应该进入 actuaöl 替换功能,以便根据需要具有通用性。