news 2026/6/16 4:40:18

R语言数据清洗与整理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
R语言数据清洗与整理

# 1. 读取数据

# ------------------------------------------------------------ # 1. 设置文件路径 # ------------------------------------------------------------ file_path <- "G:/学生成绩/学生成绩NA.csv" output_dir <- "G:/学生成绩/数据清洗结果" if (!dir.exists(output_dir)) { dir.create(output_dir, recursive = TRUE) } # ------------------------------------------------------------ # 2. 检查文件是否存在 # ------------------------------------------------------------ if (file.exists(file_path)) { cat("文件存在,可以读取。\n") } else { stop("文件不存在,请检查路径是否正确。") } # ------------------------------------------------------------ # 3. 读取 CSV 文件 # ------------------------------------------------------------ student_score <- read.csv( file = file_path, header = TRUE, # TRUE 表示第一行是列名 fileEncoding = "GB18030", # 防止中文乱码 check.names = FALSE, # 不自动修改中文列名 na.strings = c("", "NA", "NaN", "N/A", "缺失", "NULL") )

#2. 基本查看

cat("\n========== 数据前6行 head() ==========\n") print(head(student_score)) cat("\n========== 数据结构 str() ==========\n") str(student_score) cat("\n========== 描述性统计 summary() ==========\n") print(summary(student_score)) cat("\n========== 数据维度 ==========\n") cat("行数:", nrow(student_score), "\n") cat("列数:", ncol(student_score), "\n")

# 3. 数据类型初步处理

# 一般情况下,“姓名”“学生ID”为字符型,其余成绩列为数值型。
# 如果成绩列因为缺失或特殊字符被读成字符型,这里尝试转换为数值型。

id_cols <- c("姓名", "学生ID") score_cols <- setdiff(names(student_score), id_cols) for (col in score_cols) { student_score[[col]] <- suppressWarnings(as.numeric(student_score[[col]])) } cat("\n========== 类型转换后的数据结构 ==========\n") str(student_score)

# 4. 缺失值识别 is.na()

cat("\n========== 缺失值逻辑矩阵前6行 is.na() ==========\n") print(head(is.na(student_score)))

# 5. 缺失值统计

missing_count <- colSums(is.na(student_score)) missing_rate <- round( missing_count / nrow(student_score), 4 ) missing_summary <- data.frame( 变量名 = names(student_score), 缺失值个数 = as.integer(missing_count), 缺失比例 = missing_rate, check.names = FALSE ) cat("\n========== 各变量缺失值统计 ==========\n") print(missing_summary) missing_output_file <- file.path(output_dir, "缺失值统计.csv") write.csv( missing_summary, file = missing_output_file, row.names = FALSE, fileEncoding = "GB18030" ) cat("\n缺失值统计结果已保存到:\n") cat(missing_output_file, "\n")

# 6. 删除含缺失值的行

student_score_delete_na <- na.omit(student_score) cat("\n========== 删除缺失值后的数据维度 ==========\n") cat("原始数据行数:", nrow(student_score), "\n") cat("删除缺失值后行数:", nrow(student_score_delete_na), "\n") delete_na_file <- file.path(output_dir, "删除缺失值后的学生成绩.csv") write.csv( student_score_delete_na, file = delete_na_file, row.names = FALSE, fileEncoding = "GB18030" ) cat("\n删除缺失值后的数据已保存到:\n") cat(delete_na_file, "\n")

# 7. 均值填充缺失值

student_score_mean_fill <- student_score numeric_cols <- names(student_score_mean_fill)[sapply(student_score_mean_fill, is.numeric)] for (col in numeric_cols) { mean_value <- mean(student_score_mean_fill[[col]], na.rm = TRUE) student_score_mean_fill[[col]][is.na(student_score_mean_fill[[col]])] <- mean_value } cat("\n========== 均值填充后的数据前6行 ==========\n") print(head(student_score_mean_fill)) mean_fill_file <- file.path(output_dir, "均值填充后的学生成绩.csv") write.csv( student_score_mean_fill, file = mean_fill_file, row.names = FALSE, fileEncoding = "GB18030" ) cat("\n均值填充后的数据已保存到:\n") cat(mean_fill_file, "\n")

# 8. 中位数填充缺失值

student_score_median_fill <- student_score numeric_cols <- names(student_score_median_fill)[sapply(student_score_median_fill, is.numeric)] for (col in numeric_cols) { median_value <- median(student_score_median_fill[[col]], na.rm = TRUE) student_score_median_fill[[col]][is.na(student_score_median_fill[[col]])] <- median_value } cat("\n========== 中位数填充后的数据前6行 ==========\n") print(head(student_score_median_fill)) median_fill_file <- file.path(output_dir, "中位数填充后的学生成绩.csv") write.csv( student_score_median_fill, file = median_fill_file, row.names = FALSE, fileEncoding = "GB18030" ) cat("\n中位数填充后的数据已保存到:\n") cat(median_fill_file, "\n")

# 9. 箱线图法识别异常值

# 箱线图法基于 IQR: # 下界 = Q1 - 1.5 * IQR # 上界 = Q3 + 1.5 * IQR # 小于下界或大于上界的值视为异常值。 outlier_result <- data.frame( 变量名 = character(), Q1 = numeric(), Q3 = numeric(), IQR = numeric(), 下界 = numeric(), 上界 = numeric(), 异常值个数 = integer(), 异常值 = character(), check.names = FALSE ) for (col in numeric_cols) { x <- student_score[[col]] x_no_na <- x[!is.na(x)] Q1 <- quantile(x_no_na, 0.25) Q3 <- quantile(x_no_na, 0.75) IQR_value <- IQR(x_no_na) lower_bound <- Q1 - 1.5 * IQR_value upper_bound <- Q3 + 1.5 * IQR_value outliers <- x_no_na[x_no_na < lower_bound | x_no_na > upper_bound] outlier_result <- rbind( outlier_result, data.frame( 变量名 = col, Q1 = as.numeric(Q1), Q3 = as.numeric(Q3), IQR = as.numeric(IQR_value), 下界 = as.numeric(lower_bound), 上界 = as.numeric(upper_bound), 异常值个数 = length(outliers), 异常值 = paste(outliers, collapse = "; "), check.names = FALSE ) ) } cat("\n========== 箱线图法异常值识别结果 ==========\n") print(outlier_result) outlier_file <- file.path(output_dir, "箱线图异常值识别结果.csv") write.csv( outlier_result, file = outlier_file, row.names = FALSE, fileEncoding = "GB18030" ) cat("\n异常值识别结果已保存到:\n") cat(outlier_file, "\n")

# 10. 绘制箱线图

boxplot_dir <- file.path(output_dir, "箱线图") if (!dir.exists(boxplot_dir)) { dir.create(boxplot_dir, recursive = TRUE) } for (col in numeric_cols) { png_file <- file.path(boxplot_dir, paste0(col, "_箱线图.png")) png( filename = png_file, width = 800, height = 600 ) boxplot( student_score[[col]], main = paste0(col, " 箱线图"), ylab = col, col = "lightblue", border = "gray30" ) dev.off() } cat("\n所有数值变量的箱线图已保存到:\n") cat(boxplot_dir, "\n")

# 11. 生成异常值明细表

outlier_detail <- data.frame() for (col in numeric_cols) { x <- student_score[[col]] x_no_na <- x[!is.na(x)] Q1 <- quantile(x_no_na, 0.25) Q3 <- quantile(x_no_na, 0.75) IQR_value <- IQR(x_no_na) lower_bound <- Q1 - 1.5 * IQR_value upper_bound <- Q3 + 1.5 * IQR_value outlier_index <- which(!is.na(x) & (x < lower_bound | x > upper_bound)) if (length(outlier_index) > 0) { temp <- data.frame( 行号 = outlier_index, 姓名 = student_score$姓名[outlier_index], 学生ID = student_score$学生ID[outlier_index], 变量名 = col, 异常值 = student_score[[col]][outlier_index], 下界 = as.numeric(lower_bound), 上界 = as.numeric(upper_bound), check.names = FALSE ) outlier_detail <- rbind(outlier_detail, temp) } } cat("\n========== 异常值明细 ==========\n") print(outlier_detail) outlier_detail_file <- file.path(output_dir, "异常值明细表.csv") write.csv( outlier_detail, file = outlier_detail_file, row.names = FALSE, fileEncoding = "GB18030" ) cat("\n异常值明细表已保存到:\n") cat(outlier_detail_file, "\n")

# 12. 最终提示

cat("\n========== 数据清洗与异常值识别完成 ==========\n") cat("结果文件夹:\n") cat(output_dir, "\n")
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/16 4:36:51

银行排队模拟:时间驱动算法详解与C++实现

1. 项目概述&#xff1a;银行排队问题的核心逻辑银行排队问题&#xff0c;尤其是“单队列多窗口服务”这个场景&#xff0c;是数据结构与算法课程里一个非常经典的模拟题。我第一次接触它是在准备算法竞赛的时候&#xff0c;当时觉得这不就是个简单的队列模拟吗&#xff1f;但真…

作者头像 李华
网站建设 2026/6/16 4:36:50

机器学习堆叠模型实战:原理、实现与性能优化指南

1. 项目概述&#xff1a;从“单打独斗”到“团队作战”的模型进化在机器学习的世界里&#xff0c;我们常常面临一个经典的困境&#xff1a;单个模型的表现似乎遇到了瓶颈&#xff0c;无论怎么调参、换算法&#xff0c;准确率或效果就是卡在一个点上不去。这就像让一个专家去解决…

作者头像 李华
网站建设 2026/6/16 4:34:54

二-五混合进制计数器原理与应用:从74LS90到任意进制设计

1. 项目概述&#xff1a;从“奇怪”的进制到实用的计数逻辑最近在整理一些老项目的设计笔记&#xff0c;翻到了一个挺有意思的电路模块——二-五混合进制计数器。乍一听这个名字&#xff0c;可能很多刚接触数字电路的朋友会觉得有点懵&#xff1a;“二进制”和“五进制”我们都…

作者头像 李华
网站建设 2026/6/16 4:33:56

2000-2024年县域社会保险与福利数据

数据介绍数据整理全国各县社会保险与福利数据&#xff0c;包括城镇居民基本医疗保险参保人数&#xff0c;事业保险人数&#xff0c;新农村社保合作医疗等参保人数等数据。数据来源县域数据库&#xff0c;部分缺失较多。数据名称&#xff1a;县域社会保险与福利数据数据年份&…

作者头像 李华
网站建设 2026/6/16 4:31:54

氧化铝单晶:从宝石到半导体与激光硬核材料的制备与应用

1. 项目概述&#xff1a;从实验室到产业&#xff0c;揭秘“红宝石”的硬核之路提到“corundum”&#xff0c;很多人第一反应是珠宝店里璀璨的红宝石或蓝宝石。没错&#xff0c;刚玉&#xff08;Corundum&#xff09;正是这些名贵宝石的矿物学名称。但如果你以为它的价值仅仅停留…

作者头像 李华
网站建设 2026/6/16 4:28:56

Transformer长文本处理实战:语义分块与加权合并技术

1. 项目概述&#xff1a;为什么长文本让Transformer“喘不过气”&#xff0c;而分块合并是眼下最务实的解法Transformer模型处理长文本时卡顿、OOM、效果断崖式下跌——这几乎是我过去三年在NLP工程落地中听到最多的一句抱怨。不是模型不行&#xff0c;是原始设计就带着“内存天…

作者头像 李华