京公网安备 11010802034615号
经营许可证编号:京B2-20210330
如何使用R语言解决可恶的脏数据
在数据分析过程中最头疼的应该是如何应付脏数据,脏数据的存在将会对后期的建模、挖掘等工作造成严重的错误,所以必须谨慎的处理那些脏数据。
脏数据的存在形式主要有如下几种情况:
1)缺失值
2)异常值
3)数据的不一致性
下面就跟大家侃侃如何处理这些脏数据。
一、缺失值
缺失值,顾名思义就是一种数据的遗漏,根据CRM中常见的缺失值做一个汇总:
1)会员信息缺失,如身份证号、手机号、性别、年龄等
2)消费数据缺失,如消费次数、消费金额、客单价,卡余等
3)产品信息缺失,如批次、价格、折扣、所属类别等
根据实际的业务需求不同,可以对缺失值采用不同的处理办法,如需要给会员推送短信,而某些会员恰好手机号不存在,可以考虑剔除;如性别不知道,可以使用众数替代;如年龄未知,可以考虑用均值替换。当然还有其他处理缺失值的办法,如多重插补法。下面以一个简单的例子,来说明缺失值的处理。
#模拟一批含缺失值的数据集
set.seed(1234)
Tel <- 13812341000:13812341999
Sex <- sample(c('F','M'), size = 1000, replace = T, prob = c(0.4,0.6))
Age <- round(runif(n = 1000, min = 18, max = 60))
Freq <- round(runif(n = 1000, min = 1, max = 368))
Amount <- rnorm(n = 1000, mean = 134, sd = 10)
ATV <- runif(n = 1000, min = 23, max = 138)
df <- data.table(Tel = Tel, Sex = Sex, Age = Age, Freq = Freq, Amount= Amount, ATV = ATV)
上面的数据框是一个不含有任何缺失值的数据集,现在我想随机产生100个缺失值,具体操作如下:
查看原始数据集的概要
summary(df)
随机参数某行某列的下标
set.seed(1234)
i <- sample(1:6, size = 100, replace = T)
j <- sample(1:1000, size = 100)
将下标组合成矩阵
index <- as.matrix(data.frame(j,i))
将原始数据框转换为矩阵
df <- as.matrix(df)
将随机参数的行列赋值为NA
df[index] <- NA
重新将矩阵转换为数据框
df2 <- as.data.frame(df)
变换变量类型
df2$Age <- as.integer(df2$Age)
df2$Freq <- as.integer(df2$Freq)
df2$Amount <- as.numeric(df2$Amount)
df2$ATV <- as.numeric(df2$ATV)
再一次查看赋予缺失值后的数据框概要
summary(df2)

很明显这里已经随机产生100个缺失值了,下面看看这100个缺失值的分布情况。我们使用VIM包中的aggr()函数绘制缺失值的分布情况:
library(VIM)
aggr(df2, prop = FALSE, numbers = TRUE)

图中显示:Tel变量有21个缺失,Sex变量有28个缺失,Age变量有6个缺失,Freq变量有20个缺失,Amount变量有13个缺失,ATV有12个缺失。
为了演示,下面对Tel变量缺失的观测进行剔除;对Sex变量的缺失值用众数替换;Age变量用平均值替换;Freq变量、Amount变量和ATV变量用多重插补法填充。
剔除Tel变量的缺失观测
df3 <- df2[is.na(df2$Tel)==FALSE,]
分别用众数和均值替换性别和年龄
性别的众数
Sex_mode <- names(which.max(table(df3$Sex)))
年龄的均值
Age_mean <- mean(df3$Age, na.rm = TRUE)
library(tidyr)
df3 <- replace_na(df3,replace = list(Sex = Sex_mode, Age = Age_mean))
summary(df3)

这个时候,Tel变量、Sex变量和Age变量已不存在缺失值,下面对Freq变量、Amount变量和ATV变量使用多重插补法。
可通过mice包实现多重插补法,该包可以对数值型数据和因子型数据进行插补。
对于数值型数据,默认使用随机回归添补法(pmm);对二元因子数据,默认使用Logistic回归添补法(logreg);对多元因子数据,默认使用分类回归添补法(polyreg)。
其他插补法,可通过?mice查看相关文档。
library(mice)
对缺失值部分,进行5次的多重插补,这里默认使用随机回归添补法(pmm)
imp <- mice(data = df3, m = 5)
查看一下插补的结果
imp$imp
计算5重插补值的均值
Freq_imp <- apply(imp$imp$Freq,1,mean)
Amount_imp <- apply(imp$imp$Amount,1,mean)
ATV_imp <- apply(imp$imp$ATV,1,mean)
并用该均值替换原来的缺失值
df3$Freq[is.na(df3$Freq)] <- Freq_imp
df3$Amount[is.na(df3$Amount)] <- Amount_imp
df3$ATV[is.na(df3$ATV)] <- ATV_imp
再次查看填补完缺失值后的数据集和原始数据集概况
summary(df3)
summary(df2)

通过不同的方法将缺失值数据进行处理,从上图可知,通过填补后,数据的概概览情况基本与原始数据相近,说明填补过程中,基本保持了数据的总体特征。
二、异常值
异常值也是非常痛恨的一类脏数据,异常值往往会拉高或拉低数据的整体情况,为克服异常值的影响,我们需要对异常值进行处理。首先,我们需要识别出哪些值是异常值或离群点,其次如何处理这些异常值。下面仍然以案例的形式,给大家讲讲异常值的处理:
1、识别异常值
一般通过绘制盒形图来查看哪些点是离群点,而离群点的判断标准是四分位数与四分位距为基础。
即离群点超过上四分位数的1.5倍四分位距或低于下四分位数的1.5倍四分位距。
例子:
随机产生一组数据
set.seed(1234)
value <- c(rnorm(100, mean = 10, sd = 3), runif(20, min = 0.01, max
= 30), rf(30, df1 = 5, df2 = 20))
绘制箱线图,并用红色的方块标注出异常值
library(ggplot2)
ggplot(data = NULL, mapping = aes(x ='', y = value)) + geom_boxplot(outlier.colour = 'red', outlier.shape = 15, width = 1.2)

图中可知,有一部分数据落在上四分位数的1.5倍四分位距之上,即异常值,下面通过编程,将异常值找出来:
计算下四分位数、上四分位数和四分位距
QL <- quantile(value, probs = 0.25)
QU <- quantile(value, probs = 0.75)
QU_QL <- QU-QL
QL;QU;QU_QL

2、找出异常点
which(value > QU + 1.5*QU_QL)
value[which(value > QU + 1.5*QU_QL)]

结果显示,分别是第104、106、110、114、116、118和120这6个点。下面就要处理这些离群点,一般有两种方法,即剔除或替补。剔除很简单,但有时剔除也会给后面的分析带来错误的结果,接下来就讲讲替补。
用离异常点最近的点替换
test01 <- value
out_imp01 <- max(test01[which(test01 <= QU + 1.5*QU_QL)])
test01[which(test01 > QU + 1.5*QU_QL)] <- out_imp01
用上四分位数的1.5倍四分位距或下四分位数的1.5倍四分位距替换
test02 <- value
out_imp02 <- QU + 1.5*QU_QL
test02[which(test02 > QU + 1.5*QU_QL)] <- out_imp02
对比替换前后的数据概览
summary(value)
summary(test01)
summary(test02)

三、数据的不一致性
数据的不一致性一般是由于不同的数据源导致,如有些数据源的数据单位是斤,而有些数据源的数据单位为公斤;如有些数据源的数据单位是米,而有些数据源的数据单位为厘米;如两个数据源的数据没有同时更新等。对于这种不一致性可以通过数据变换轻松得到一致的数据,只有数据源的数据一致了,才可以进行统计分析或数据挖掘。由于这类问题的处理比较简单,这里就不累述具体的处理办法了。
即使只是凡世中一颗小小的尘埃,命运也要由自己主宰,像向日葵般,迎向阳光、勇敢盛开
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
【核心关键词】模块、餐饮、客户、门店、企业、订单、供应链、多样化、产品、生产计划、数据分析、生产管理、物料管理、业务分 ...
2026-07-16在数字化分析时代,原始数据本身不具备业务价值,只有通过科学的统计学方法加工、拆解、验证与解读,才能挖掘数据背后的规律、差 ...
2026-07-16 很多数据分析师能熟练地写SQL、做透视表、算描述性统计,但当被问到“如何预测用户流失概率”“如何归因销量下滑的关键因素 ...
2026-07-16在描述性统计分析、数据预处理、异常值排查与多组数据分布对比工作中,箱线图(Box Plot)是应用最广泛的可视化与统计工具之一。 ...
2026-07-15在企业数据存储、业务统计与数据分析工作中,绝大多数业务数据都带有时间维度属性,例如订单创建时间、用户注册时间、支付完成时 ...
2026-07-15 很多数据分析师拿到数据就开始清洗、建模,但当被问到“这批数据属于什么类型——结构化还是非结构化?分类变量还是数值变量 ...
2026-07-15【核心关键词】产品、经营、客户、调研、销售额、宏观、会计行业、客户满意度、发展趋势、经营状况、数据分析、竞争对手、数据 ...
2026-07-14问卷调查是市场调研、用户研究、社会调研与产品分析的核心数据采集方式。问卷数据大多以分类数据为主,例如用户性别、年龄分层、 ...
2026-07-14 很多数据分析师画过趋势图、做过业绩预测,但当被问到“这个月销售额增长20%,到底是长期趋势自然增长,还是促销活动的短期 ...
2026-07-14在数据分析、业务效果验证、AB实验扩展、行业对比等场景中,我们经常需要对比三组及以上样本的均值差异,例如不同区域的客单价对 ...
2026-07-13在互联网产品运营、用户生命周期管理与商业化数据分析中,留存指标是判断产品价值、用户满意度与商业模式健康度的核心基准。常规 ...
2026-07-13 很多数据分析师做过按月份的销售额趋势图,画过按天的流量折线图,但当被问到“时间序列和普通数据有什么本质区别”“季节性 ...
2026-07-13【核心关键词】统计学、互联网、知识、课程、学生、数学、软件、招聘、数据分析、实习经历、机器学习、理论基础、业务思维、统 ...
2026-07-10在互联网运营、产品设计、市场营销与商业数据分析领域,所有转化、成交、复购行为的底层逻辑,都依托于用户决策流程。用户从产生 ...
2026-07-10 很多数据分析师能熟练地计算指标、搭建标签体系,但当被问到“画像到底在解决什么问题”“画像和标签是什么关系”“画像如何 ...
2026-07-10数据透视表是数据分析中最常用、最高效的汇总分析工具,具备快速分组、聚合计算、维度拆解、数据可视化等优势,能够轻松完成求和 ...
2026-07-09在统计学、CDA数据分析、机器学习与商业数据研究中,正态分布是最基础、最重要的数据分布形态。绝大多数参数检验、数据建模、指 ...
2026-07-09 很多分析师在设计标签时思路清晰,但真到落地环节却面临“数据在手,不知如何转化为可用标签”的困境:或因加工方式选择不当 ...
2026-07-09【核心关键词】采购、周期、原材料、企业、产品、成本、要素、库存、供应商、数据分析、生产计划、生产制造、加工制造、技术工 ...
2026-07-08在数据分析、特征工程、机器学习建模的工作流程中,原始数据往往包含多个不同维度的数值指标,例如客户交易数据中的消费金额、交 ...
2026-07-08