如何在R中提取行内周数并整理非结构化CSV数据用于绘图
R语言实现非结构化CSV数据重排方案
推荐依赖库
你可以直接使用tidyverse生态工具链完成全流程处理,不需要依赖外部Python脚本:
readr:按行读取原始文本stringr:字符串匹配、提取dplyr:数据清洗与分组计算tidyr:表结构转换
完整实现代码
# 加载依赖 library(tidyverse) # 1. 按行读取原始数据,避免read.csv直接识别列导致的结构混乱 raw_lines <- readLines("mydata.csv") # 2. 标注周数、过滤无效行 data_with_week <- tibble(line = raw_lines) %>% # 识别周数标记行 mutate(is_week_line = str_detect(line, "sometext for week"), # 按周数行分组,同组属于同一周的数据 week_group = cumsum(is_week_line), # 提取周数数值 week = as.integer(str_extract(line, "(?<=week )\\d+"))) %>% # 把周数填充到同组的所有行 group_by(week_group) %>% fill(week, .direction = "down") %>% ungroup() %>% # 过滤掉周数行、表头行,只保留有效数据行 filter(!is_week_line, !str_detect(line, "headertext")) # 3. 拆分数据列、转成适合绘图的长表格式 plot_ready_data <- data_with_week %>% # 按逗号拆分每行的字段 separate(line, into = c("data_type", "v1", "v2", "v3"), sep = ",", fill = "right") %>% # 清洗字段里的引号、空格,转成数值格式 mutate(across(c(v1, v2, v3), ~ as.integer(str_remove_all(.x, '["\\s]')))) %>% # 转长表,完成最终格式转换 pivot_longer(cols = c(v1, v2, v3), names_to = "year_index", values_to = "value") %>% select(week, data_type, value)
如果需要严格匹配每周表头对应的不同年份,可额外增加一步提取每个周对应表头年份的逻辑,和上述流程关联即可得到你示例中带年份的最终格式。
原生R实现方案
如果你不想引入第三方包,也可以用R原生函数实现,逻辑和你提供的Python代码完全一致:
con <- file("mydata.csv", "r") week <- NULL result <- c() while(length(line <- readLines(con, n = 1)) > 0) { if (startsWith(line, "sometext")) { week <- trimws(gsub(".*week (\\d+).*", "\\1", line)) } else if (!startsWith(line, "headertext")) { result <- c(result, paste0(week, ",", line)) } } close(con) # 解析为数据框 final_data <- read.csv(text = result, header = FALSE)
内容的提问来源于stack exchange,提问作者user2567875
相关产品推荐
相关产品推荐

