数据探索基础:summary、str、head、glimpse、基本统计量

拿到一个新数据集,你第一件事会做什么?

我见过不少新手直接就开始建模,结果跑出来的模型连自己都看不懂——说白了就是没摸透数据。我个人习惯在特征工程之前,先花 10 分钟做一轮快速数据探索。这步做充分了,后面能省下大量返工时间。

数据探索的整体流程

把数据当成一个陌生人,你要先看它的“长相”(行数、列名、数据类型),再看它的“性格”(缺失情况、分布、异常值)。通常我是按这个顺序来的:

  1. 用 head() 瞄一眼前几行,确认列名和值对不对。
  2. 用 str() 看结构,有没有因子,有没有字符型。写代码。
  3. 换成 glimpse() 再扫一遍,视觉上更舒服。
  4. 用 summary() 拿到五数摘要和频率表。
  5. 用基本统计量函数(mean、median、sd、quantile)深入分析感兴趣的特征。

下面这张图把这个流程画出来了,你可以存起来当检查表。

数据探索流程 获得数据集 head() 快速预览 可选择 str() 查看结构 glimpse() 增强版结构 summary() 统计摘要 mean / median / sd / quantile 避坑提醒 • summary 遇因子直接给频数 • 数值列有NA时记得na.rm=T • head()默认6行,可改n参数
💡 我的习惯:每次拿到新数据,我都会在脚本顶部先写四行:head(data) ; str(data) ; glimpse(data) ; summary(data)。这样整数据的大致轮廓就有了。

逐个工具实战拆解

1. head() —— 先看看样子

head() 默认给你前 6 行数据。我觉得它最大的用处是快速确认列名、单位、是否读对了分隔符。有一次我在项目里读 CSV 时忘了加 stringsAsFactors=FALSE,结果 head() 一看,全是整数,吓得我赶紧改参数。

head(iris)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa

# 想看更多行?
head(iris, n = 10)

2. str() —— 结构解剖刀

str() 会告诉你每列的数据类型、因子水平的前几个值、行数。我特别依赖它来检查是不是有“伪数值”列——比如价格字段因为混了逗号被读成了字符型。这东西很隐蔽,但 str() 一眼就能揪出来。

str(iris)
# 'data.frame':	150 obs. of  5 variables:
#  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 ...
#  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 ...
#  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 ...
#  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 ...
#  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 ...
⚠️ 我曾经踩过的坑:多年前处理一个客户数据集,看到str()显示年龄列是字符型,没在意直接建模,结果模型预测全是负数。原因是有些样本写了“18岁”,读成字符了。自那以后我对数据类型格外敏感。

3. glimpse() —— 更清爽的结构查看器

glimpse() 来自 dplyr 包,其实是 str() 的“颜值升级版”。它会横向排列每列,直接展示前几个值,看起来像一张漂亮的数据卡片。我个人在交互式探索时更爱用它,因为眼睛不用上下滚动。

library(dplyr)
glimpse(iris)
# Rows: 150
# Columns: 5
# $ Sepal.Length  5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9, ...
# $ Sepal.Width   3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, ...
# $ Petal.Length  1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, ...
# $ Petal.Width   0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.2, ...
# $ Species       setosa, setosa, setosa, setosa, setosa, setosa, set...

4. summary() —— 一页纸的统计快照

这是我最频繁调用的函数,没有之一。对数值列它会输出最小值、第一四分位、中位数、均值、第三四分位、最大值。对因子它会输出各类的频数。连续看几列,异常值(比如负数当正数)、缺失值(NA 的数量)马上现形。

summary(iris)
#   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
#  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100   setosa    :50  
#  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300   versicolor:50  
#  Median :5.800   Median :3.000   Median :4.350   Median :1.300   virginica :50  
#  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199                  
#  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800                  
#  Max.   :7.900   Max.   :4.400   Max.   :6.900

你看,Petal.Length 的最小值是 1.0,最大值是 6.9,跨度很大——对于特征工程来说,这种变量可能需要标准化或对数变换。

5. 基本统计量函数 —— 深入细节

有时候 summary() 给的粒度还不够。比如我想知道标准差,或者指定百分位数。那就用下面这些核心函数:

mean(iris$Sepal.Length, na.rm = TRUE)      # 5.843333
median(iris$Sepal.Length)                  # 5.8
sd(iris$Sepal.Length)                      # 0.8280661
quantile(iris$Sepal.Length, probs = c(0.1, 0.9))  # 10% 和 90% 分位点
# 10% 90% 
# 4.8  6.9
🔑 关键记忆:只要看到 NA 出现,mean()、sd() 这些函数必须加上 na.rm = TRUE,否则返回 NA。这是新手最容易犯的错——我当年因为这个被代码折磨了一整天,后来把“na.rm”直接焊在了条件反射里。

工具对比一览表

选哪个工具,取决于你想看什么。下面这张表帮你快速决策:

函数 最适合的场景 输出特点
head() 快速看前几行数据,确认导入是否正确 数据框的前 n 行,默认 6 行
str() 检查每列数据类型、因子水平、缺失情况 列名 + 类型 + 前几个值,紧凑存储
glimpse() 交互式探索,更直观的数据结构展示 类似 str,但横向布局,值更完整
summary() 数值变量的五数汇总+均值,因子变量频数 每列一个分节,数值列六数,因子列计数
mean / median / sd / quantile 针对单列做精确统计,自定义分位点 返回单个数值或向量
✏️ 效率小技巧:在 RStudio 里直接运行 summary(df) 然后翻看“Console”窗口,比在 View() 里点来点去快得多。你可以试试把常用探索命令写成一个短的函数,比如 explore <- function(x) { list(head= head(x), str= str(x), summary= summary(x)) },一键搞定。

实战综合演练

假设我们拿到了 airquality 这个内置数据集(纽约空气质量数据)。按刚才的流程跑一遍:

data(airquality)
head(airquality)
str(airquality)
glimpse(airquality)
summary(airquality)

你会看到 summary() 输出里 Ozone 列有 37 个 NA——这直接告诉你缺失值严重,后续必须处理。另外 Solar.R 也有 7 个 NA。很多人在特征工程早期忽略了这些,等建模才发现模型报错,白折腾。

这就是数据探索的价值。

好了,这一轮探索下来,你应该对数据集的骨架和血型都摸清了。接下来再做缺失值填充、异常值处理、特征构造,心里就有底了。