如何在R Shiny中上传多份CSV文件并利用文件名重命名重复值
问题解决:Shiny上传多文件并处理重复列值
可复现数据
生成测试用CSV文件的R代码:
file1 <- data.frame(animal = c('cat','dog','horse'), w = c(10,20,30)) file2 <- data.frame(animal = c('pig','dog','bat'), w = c(11,22,33)) file3 <- data.frame(animal = c('dog','eagle','horse'), w = c(110,220,330)) write.csv(file1, 'foobar_TEST_1.csv', row.names = FALSE) write.csv(file2, 'foobar_TEST_2.csv', row.names = FALSE) write.csv(file3, 'foobar_TEST_3.csv', row.names = FALSE)
需求说明
上传上述3份CSV文件后,对animal列的重复值进行处理:仅为重复出现的项添加对应文件名的后缀部分(如TEST_1、TEST_2),首次出现的原始项保持不变。例如处理后animal列的值应为:cat、dog、horse、pig、dog_TEST_2、bat、dog_TEST_3、eagle、horse_TEST_3。
现有Shiny代码
ui <- fluidPage( sidebarPanel( fileInput(inputId = "animal", label = "上传多份文件", multiple = TRUE, accept = c("text/csv", "text/comma-separated-values,text/plain", ".csv"))), mainPanel( DT::dataTableOutput("table1"))) server <- function(input, output, session) { data <- reactive({ req(input$animal) inFile <- input$animal$datapath df <- lapply(inFile, function(y){ files <- read.csv(y, header=TRUE) }) final <- do.call(rbind, df) list(final = final) }) output$table1 <- DT::renderDataTable({ final <- data()$final datatable(data = final) }) } shinyApp(ui = ui, server = server)
修改后的实现(在reactive中完成处理)
修改server中的reactive部分,实现重复值的命名处理:
library(dplyr) server <- function(input, output, session) { data <- reactive({ req(input$animal) # 获取文件路径和文件名 file_paths <- input$animal$datapath file_names <- input$animal$name # 读取每个文件并添加后缀信息 df_list <- mapply(function(path, name) { # 提取文件名后缀(如从foobar_TEST_1.csv中提取TEST_1) suffix <- sub("^foobar_(.*)\\.csv$", "\\1", name) df <- read.csv(path, header = TRUE) # 添加后缀列,用于后续处理 df$file_suffix <- suffix df }, path = file_paths, name = file_names, SIMPLIFY = FALSE) # 合并所有数据框 final_df <- do.call(rbind, df_list) # 处理animal列的重复值:仅非首次出现的项添加后缀 final_df <- final_df %>% group_by(animal) %>% mutate( animal = ifelse(row_number() == 1, animal, paste0(animal, "_", file_suffix)) ) %>% ungroup() %>% select(-file_suffix) # 移除临时后缀列 list(final = final_df) }) output$table1 <- DT::renderDataTable({ datatable(data()$final) }) }
关键步骤说明
- 提取文件名后缀:通过正则表达式从文件名中提取
TEST_*部分,用于后续拼接。 - 添加临时后缀列:给每个数据框添加对应文件的后缀信息,方便后续分组处理。
- 分组处理重复值:按
animal分组,对每组中除第一行外的项,将animal值与后缀拼接;第一行保持原始值。 - 清理临时列:处理完成后移除添加的
file_suffix列,保持数据整洁。
内容的提问来源于stack exchange,提问作者purple1437
相关产品推荐
相关产品推荐

