如何替换数据表中值的单个组件?
How can I replace a single component of a value in a Datatable?
我正在尝试在 R shiny 应用程序中用 100,066,008,100,066,008 替换变量“030,066,008,030,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)
一个可能的解决方案使用 stringr
。我刚刚从 stringr
包中通过 str_replace_all
更改了 replace
函数。
编辑:您可以使用正则表达式作为检测模式,以指定您要检测的确切数字,而不是它是否是另一个数字的一部分。
示例:str_replace_all("0300", "030", "100")
将 return 1000 而
str_replace_all("0300", my_regex("030"), "100")
将 return 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)
我假设您想按列和按行过滤数据集,并假设行值始终是 ID(如果不是,您可以为此添加另一个 selectInput)
注意:使用 stringr::str_replace_all
实际上更聪明,但由于我用了整个下午,我还是想 post 我的解决方案...
注意 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)
我正在尝试在 R shiny 应用程序中用 100,066,008,100,066,008 替换变量“030,066,008,030,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)
一个可能的解决方案使用 stringr
。我刚刚从 stringr
包中通过 str_replace_all
更改了 replace
函数。
编辑:您可以使用正则表达式作为检测模式,以指定您要检测的确切数字,而不是它是否是另一个数字的一部分。
示例:str_replace_all("0300", "030", "100")
将 return 1000 而
str_replace_all("0300", my_regex("030"), "100")
将 return 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)
我假设您想按列和按行过滤数据集,并假设行值始终是 ID(如果不是,您可以为此添加另一个 selectInput)
注意:使用 stringr::str_replace_all
实际上更聪明,但由于我用了整个下午,我还是想 post 我的解决方案...
注意 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)