【问题标题】:How can values of a datatable be replaced in R shiny如何在 R Shiny 中替换数据表的值
【发布时间】:2021-11-25 18:36:40
【问题描述】:

我正在创建一个简单的 R 闪亮应用程序,用户在其中上传 .CSV 文件并在主面板中呈现数据表,并在“选择列”部分自动突出显示列名。

我正在寻找的是:

如何替换值? (从旧值到新值)。例如,我应该如何通过引用“选择列”中的列名来修改“范围”列中的值 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)

【问题讨论】:

  • 为什么不在renderDT 中使用editable 选项?您获得可编辑的数据表而无需自己定义不断变化的 UI?参看。 yihui.shinyapps.io/DT-edit
  • @thothal,我只展示了我原始 CSV 的一小部分,它有超过 1000 行数据。我宁愿保留一个单击即可替换所有内容的按钮。

标签: r shiny rscript


【解决方案1】:

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

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 向量。如果之前是数字,我重新转换该值。还有一些其他数据类型尚未考虑,因此应该考虑一下实际替换功能,以便根据需要实现通用性。

【讨论】:

  • 是的,效果很好
猜你喜欢
  • 2018-07-02
  • 2021-11-28
  • 2020-04-30
  • 2021-12-21
  • 2015-07-15
  • 2017-08-06
  • 1970-01-01
  • 2014-12-15
  • 1970-01-01
相关资源
最近更新 更多