You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)
  })
}

关键步骤说明

  1. 提取文件名后缀:通过正则表达式从文件名中提取TEST_*部分,用于后续拼接。
  2. 添加临时后缀列:给每个数据框添加对应文件的后缀信息,方便后续分组处理。
  3. 分组处理重复值:按animal分组,对每组中除第一行外的项,将animal值与后缀拼接;第一行保持原始值。
  4. 清理临时列:处理完成后移除添加的file_suffix列,保持数据整洁。

内容的提问来源于stack exchange,提问作者purple1437

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 23:15:33