R shiny如何将CSV底部行列转为表头并与上方数据并排展示
实现方案
核心处理逻辑
你需要先识别CSV文件中第二段表头的位置,拆分两段内容分别解析为独立数据框后再横向拼接,具体逻辑如下:
- 上传文件时同时存储原始文本行内容,用于后续结构识别
- 匹配第二段表头的特征(本例中表头开头为
ID字段)定位拆分点 - 两段数据分别解析后对齐行数,再横向拼接得到最终结果
修改后的完整app.R代码
library(shiny) library(reshape2) library(DT) library(tibble) ###function for deleting the rows splitColumn <- function(data, column_name) { newColNames <- c("Unmerged_type1", "Unmerged_type2") newCols <- colsplit(data[[column_name]], " ", newColNames) after_merge <- cbind(data, newCols) after_merge[[column_name]] <- NULL after_merge } ###_______________________________________________ ### function for inserting a new column fillvalues <- function(data, values, columName){ df_fill <- data vec <- strsplit(values, ",")[[1]] df_fill <- tibble::add_column(df_fill, newcolumn = vec, .after = columName) df_fill } ##function for removing the colum removecolumn <- function(df, nameofthecolumn){ df[ , -which(names(df) %in% nameofthecolumn)] } ### use a_splitme.csv for testing this program ui <- fluidPage( sidebarLayout( sidebarPanel( fileInput("file1", "Choose CSV File", accept = ".csv"), checkboxInput("header", "Header", TRUE), actionButton("mergeTwoParts", "拼接双段表格", class = "btn-success"), actionButton("Splitcolumn", "SplitColumn", class = "btn-warning" ), uiOutput("selectUI"), actionButton("replacevalues", label = 'Replace values', class= "btn-Secondary"), actionButton("removecolumn", "Remove Column"), actionButton("Undo", 'Undo', style="color: #fff; background-color: #337ab7; border-color: #2e6da4"), actionButton("deleteRows", "Delete Rows"), textInput("textbox", label="Input the value to replace:"), actionButton('downloadbtn', label= 'Download'), ), mainPanel( DTOutput("table1") ) ) ) server <- function(session, input, output) { rv <- reactiveValues(data = NULL, orig=NULL, raw_lines = 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$orig <- read.csv(file$datapath, header = input$header) rv$data <- rv$orig # 存储原始文本行用于双段结构识别 rv$raw_lines <- readLines(file$datapath, encoding = "UTF-8") }) # 双段表格拼接逻辑 observeEvent(input$mergeTwoParts, { req(rv$raw_lines) # 定位两个表头的位置,匹配规则可根据实际表头调整 header_pos <- which(grepl("^ID\\s+", rv$raw_lines)) validate(need(length(header_pos) == 2, "未检测到两段独立表头的结构,请检查文件格式")) # 解析上段数据 空白分隔如果是逗号分隔请把sep改成"," part1 <- read.table(text = rv$raw_lines[header_pos[1]:(header_pos[2]-1)], header = TRUE, sep = "", strip.white = TRUE) # 解析下段数据 part2 <- read.table(text = rv$raw_lines[header_pos[2]:length(rv$raw_lines)], header = TRUE, sep = "", strip.white = TRUE) # 对齐两段数据的行数,不足的补NA max_row <- max(nrow(part1), nrow(part2)) if(nrow(part1) < max_row) part1[(nrow(part1)+1):max_row, ] <- NA if(nrow(part2) < max_row) part2[(nrow(part2)+1):max_row, ] <- NA # 横向拼接,保留原列名 rv$data <- cbind(part1, part2) colnames(rv$data) <- c(colnames(part1), colnames(part2)) }) output$selectUI<-renderUI({ req(rv$data) selectInput(inputId='selectcolumn', label='select column', choices = 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, selection = 'none', server = F, editable = T ) #includes extra column after the 'select column' and replaces the values specified 'Input the value to replace:' observeEvent(input$replacevalues, { rv$data <- fillvalues(rv$data, input$textbox, input$selectcolumn) }) #Removing the specifield column through select column observeEvent(input$removecolumn, { rv$data <- removecolumn(rv$data,input$selectcolumn) }) observeEvent(input$Undo, { rv$data <- rv$orig }) #Storing the csv file through download button observeEvent(input$downloadbtn,{ write.csv(rv$data,'test.csv', row.names = FALSE) print ('file has been downloaded') }) observeEvent(input$downloadbtn, { showModal(modalDialog( title = "Download Status.", paste0("csv file has been downloaded",input$downloadbtn,'.'), easyClose = TRUE, footer = NULL )) }) } shinyApp(ui, server)
使用说明
- 上传符合格式的CSV文件后,点击「拼接双段表格」按钮即可自动完成两段数据的横向拼接
- 如果你的CSV是逗号分隔格式,将代码中
read.table的sep = ""修改为sep = ","即可 - 点击「Undo」按钮可撤销拼接操作,回到原始上传的数据状态
内容的提问来源于stack exchange,提问作者Kevin Tracey
相关产品推荐
相关产品推荐

