【问题标题】:How can I replace a single component of a value in a Datatable?如何替换数据表中值的单个组件?
【发布时间】:2021-12-26 08:39:41
【问题描述】:

我正在尝试在 R 闪亮的应用程序中将变量 '030,066,008,030,066,008' 替换为 100,066,008,100,066,008'。目前,它没有。当我替换所有值时,它可以工作。

重要提示:我只想替换部分值,而不是完整的集合。

有人可以帮我解决这个问题吗?

CSV 数据

ID  Type  Category    values
21  A1     B1          030,066,008,030,066,008
22  C1     D1          020,030,075,080,095,100
23  E1     F1          030,085,095,060,201,030

App.R

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

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Choose CSV File", accept = ".csv"),
      checkboxInput("header", "Header", TRUE),
      selectInput("col", "Column to search:", NULL),
      textInput("old", "Replace:"),
      textInput("new", "By:"),
      actionButton("replace", "Replace!"),
    ),
    mainPanel(
      DTOutput("table1")
    )
  )
)

server <- function(input, output, session) {
  my_data <- reactiveVal(NULL)
  
  observeEvent(input$file1, {
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "csv", "Please upload a csv file"))
    my_data(read.csv(file$datapath, header = input$header))
    updateSelectInput(session, "col", choices = names(my_data()))
  })
  
  observeEvent(input$replace, {
    req(input$col)
    dat <- req(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(
    req(my_data())
  )
}

shinyApp(ui, server)

【问题讨论】:

  • 你在“by”和“replace”框中放了什么?当我将 030,066,008,030,066,008 放入“by”框并将 100,066,008,100,066,008 放入“replace”框(表中第一行的新值然后更改为 100,066,008,100,066,008)时,它对我来说很好。
  • @NovaEthos,例如,我想在替换框中写 030,在 by 框中写 100。当我尝试它时,它没有工作。

标签: r shiny shinyapps


【解决方案1】:

使用stringr 的一种可能解决方案。我刚刚将 replace 函数从 stringr 包更改为 str_replace_all

编辑:您可以使用正则表达式作为模式进行检测,以指定您要检测的确切数字,而不是如果它是另一个数字的一​​部分。

示例:str_replace_all("0300", "030", "100") 将返回 1000 而 str_replace_all("0300", my_regex("030"), "100") 将返回 0300,my_regex 是一个正则表达式来指定你想要的确切模式(我必须承认我现在没有正则表达式在我的脑海中使用......)

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

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Choose CSV File", accept = ".csv"),
      checkboxInput("header", "Header", TRUE),
      selectInput("col", "Column to search:", NULL),
      textInput("old", "Replace:"),
      textInput("new", "By:"),
      actionButton("replace", "Replace!"),
    ),
    mainPanel(
      DTOutput("table1")
    )
  )
)

server <- function(input, output, session) {
  my_data <- reactiveVal(NULL)
  
  observeEvent(input$file1, {
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    # validate(need(ext == "csv", "Please upload a csv file"))
    my_data(read.csv2(file$datapath, header = input$header))
    updateSelectInput(session, "col", choices = names(my_data()))
  })
  
  observeEvent(input$replace, {
    req(input$col)
    dat <- req(my_data())
    traf <- if (is.numeric(dat[[input$col]])) as.numeric else identity

    my_data(dat %>%
              mutate(!!rlang::sym(input$col) := 
                       stringr::str_replace_all(!!rlang::sym(input$col),
                               input$old,
                               input$new) %>% 
                       traf()))
  })
  
  output$table1 <- renderDT(
    req(my_data())
  )
}

shinyApp(ui, server)

【讨论】:

  • 是的,它现在可以工作了。谢谢
  • @KevinTracey Pabort 是正确的,如果你有 0300 它将用 1000 替换它,也许你不想要它。但是您可以在 str_replace_all(string, pattern, replacement) 中使用正则表达式来查找要查找的模式。并且使用正则表达式,您可以指定您想要确切的“030”,而不是检测“0300”或“1030”。
【解决方案2】:

我假设您想按列和按行过滤数据集,并假设行值始终为 ID(如果不是,您可以为此添加另一个 selectInput)

注意:使用stringr::str_replace_all实际上更聪明,但由于我用了整个下午,我还是想发布我的解决方案......

注意2:stringr::str_replace_all不会用10000替换值03000吗?很好,那我的解决方案更好!

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

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Choose CSV File", accept = ".csv"),
      checkboxInput("header", "Header", TRUE),
      textInput("row", "Select row by ID:"),
      selectInput("col", "Column to search:", NULL),
      textInput("old", "Replace:", value="030"),
      textInput("new", "By:", value ="100"),
      actionButton("replace", "Replace!"),
    ),
    mainPanel(
      DTOutput("table1")
    )
  )
)

server <- function(input, output, session) {
  ## two reactVal, one for the dataset and another for the vector with new values
  my_data <- reactiveVal(NULL)
  vector1 <- reactiveVal(NULL)
  
  observeEvent(input$file1, {
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "csv", "Please upload a csv file"))
    my_data(read.csv(file$datapath, header = input$header))
    updateSelectInput(session, "col", choices = names(my_data()))
  })
  
  observeEvent(input$replace, {
    req(input$col, input$row, input$new, input$old)
    my_data <- my_data()
    old <- input$old
    new <- input$new
    col1 <- input$col
    row1 <- input$row
    ## create a new vector by:
    vector1(
      my_data %>%
        filter(ID == row1) %>%            ## 1. filtering by row
        select(all_of(col1)) %>%          ## 2. selecting column
        stringr::str_split(",") %>%       ## 3. creating a list of values separated by ','
        unlist() %>%                      ## 4. unlisting the values into a vector of values
        replace(., . == old, new)  %>%    ## 5. changing old values for new values
        paste0(collapse = ",")            ## 6. colapsing all values of vector with ','
    )
    ## replace that vector in the dataframe
    my_data <-  my_data %>% 
      mutate(values = ifelse(ID == row1, vector1(), values))
    
    my_data(my_data)
    
  })
  
  output$table1 <- renderDT(
    req(my_data())
  )
}

shinyApp(ui, server) 

【讨论】:

  • 这是相关的。我编辑了自己的问题以指定可以使用的正则表达式。
猜你喜欢
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2021-01-27
相关资源
最近更新 更多