R语言数据管理:日期值、因子、排序与计算变量

Author

蟹蟹喵

Published

June 8, 2026

1. 本节学习目标

在实际数据分析中,拿到原始数据后,通常不能直接画图或建模。
我们经常需要先对数据做一些整理,例如:

  • 把字符型日期转换成真正的日期;
  • 把分类变量转换成因子;
  • 按某个变量排序;
  • 根据已有变量计算新变量;
  • 根据条件创建分类变量;
  • 按组计算平均值、总和等。

本节主要学习以下内容:

  1. 日期值的基本处理;
  2. 因子的基本用法;
  3. 数据排序;
  4. 计算新变量;
  5. 条件变量;
  6. 简单分组汇总。

主要使用两个包:

dplyr
lubridate
作用
dplyr 数据整理,如排序、计算变量、分组汇总
lubridate 日期处理

2. 加载包

如果没有安装,可以先运行:

install.packages("dplyr")
install.packages("lubridate")

加载包:

library(dplyr)
library(lubridate)

3. 创建示例数据

先创建一份简单的销售数据。

sales <- data.frame(
  id = 1:8,
  date = c(
    "2024-01-05", "2024-01-12", "2024-02-03", "2024-02-20",
    "2024-03-01", "2024-03-15", "2024-04-02", "2024-04-18"
  ),
  region = c("华东", "华北", "华南", "华东", "华北", "华南", "华东", "华北"),
  category = c("食品", "服装", "电子", "食品", "服装", "电子", "食品", "服装"),
  price = c(20, 150, 3000, 35, 180, 2500, 28, 220),
  quantity = c(5, 2, 1, 6, 3, 1, 4, 2)
)

sales
  id       date region category price quantity
1  1 2024-01-05   华东     食品    20        5
2  2 2024-01-12   华北     服装   150        2
3  3 2024-02-03   华南     电子  3000        1
4  4 2024-02-20   华东     食品    35        6
5  5 2024-03-01   华北     服装   180        3
6  6 2024-03-15   华南     电子  2500        1
7  7 2024-04-02   华东     食品    28        4
8  8 2024-04-18   华北     服装   220        2

查看数据结构:

str(sales)
'data.frame':   8 obs. of  6 variables:
 $ id      : int  1 2 3 4 5 6 7 8
 $ date    : chr  "2024-01-05" "2024-01-12" "2024-02-03" "2024-02-20" ...
 $ region  : chr  "华东" "华北" "华南" "华东" ...
 $ category: chr  "食品" "服装" "电子" "食品" ...
 $ price   : num  20 150 3000 35 180 2500 28 220
 $ quantity: num  5 2 1 6 3 1 4 2

可以看到:

  • date 现在是字符型;
  • regioncategory 也是字符型;
  • pricequantity 是数值型。

4. 日期值基础

4.1 什么是日期值?

日期看起来像普通文字,例如:

"2024-01-05"

但在数据分析中,我们希望 R 把它识别成真正的日期。
只有这样,才能进行日期计算,例如:

  • 提取年份;
  • 提取月份;
  • 计算两个日期相差多少天;
  • 筛选某个时间段的数据。

4.2 日期格式符号基础

在 R 中,日期通常由“年、月、日”组成。
但是不同数据中的日期写法可能不一样,例如:

"2024-03-01"
"2024/03/01"
"03/01/2024"
"01-03-24"

R 需要知道这些数字分别代表什么,才能正确转换成日期。

常用日期格式符号如下:

格式符号 含义 示例
%Y 四位年份 2024
%y 两位年份 24
%m 两位月份 03
%d 两位日期 01
%B 完整月份名称 March
%b 缩写月份名称 Mar
%A 完整星期名称 Friday
%a 缩写星期名称 Fri

其中,最常用的是:

%Y
%y
%m
%d

4.3 %Y%y 的区别

%Y 表示四位年份。

as.Date("2024-03-01", format = "%Y-%m-%d")
[1] "2024-03-01"

这里:

"2024-03-01"

对应:

"%Y-%m-%d"

意思是:

数据中的部分 对应格式
2024 %Y
03 %m
01 %d

所以:

%Y = 四位年份

例如:

2024
1998
2010

%y 表示两位年份。

as.Date("24-03-01", format = "%y-%m-%d")
[1] "2024-03-01"

这里:

"24-03-01"

对应:

"%y-%m-%d"

意思是:

数据中的部分 对应格式
24 %y
03 %m
01 %d

所以:

%y = 两位年份

例如:

24
98
10

简单记忆:

符号 含义
%Y 大写 Y,四位年份
%y 小写 y,两位年份

4.4 as.Date() 中的 format 参数

as.Date() 可以把字符转换成日期。

基本形式是:

as.Date(日期字符, format = "日期格式")

例如:

as.Date("2024-03-01", format = "%Y-%m-%d")
[1] "2024-03-01"

如果日期中间用 / 分隔,那么格式也要写成 /

as.Date("2024/03/01", format = "%Y/%m/%d")
[1] "2024-03-01"

如果日期顺序是“月/日/年”,例如:

"03/01/2024"

表示 2024 年 3 月 1 日,那么应该写:

as.Date("03/01/2024", format = "%m/%d/%Y")
[1] "2024-03-01"

如果日期顺序是“日/月/年”,例如:

"01/03/2024"

表示 2024 年 3 月 1 日,那么应该写:

as.Date("01/03/2024", format = "%d/%m/%Y")
[1] "2024-03-01"

注意:

"03/01/2024"

可能表示:

  • 2024 年 3 月 1 日;
  • 也可能表示 2024 年 1 月 3 日。

所以一定要先弄清楚原始数据中的日期顺序。


4.5 format() 函数:改变日期显示格式

as.Date() 是把字符转换成日期。
format() 是把日期按照指定格式显示出来。

先创建一个日期:

date1 <- as.Date("2024-03-01")
date1
[1] "2024-03-01"

把日期显示成“年/月/日”:

format(date1, "%Y/%m/%d")
[1] "2024/03/01"

显示成“月-日-年”:

format(date1, "%m-%d-%Y")
[1] "03-01-2024"

显示成年份:

format(date1, "%Y")
[1] "2024"

显示成月份:

format(date1, "%m")
[1] "03"

显示成“年-月”:

format(date1, "%Y-%m")
[1] "2024-03"

显示成带中文的格式:

format(date1, "%Y年%m月%d日")
[1] "2024年03月01日"

结果是:

"2024年03月01日"

4.6 as.Date() 和 format() 的区别

很多初学者容易混淆 as.Date()format()

函数 作用 结果类型
as.Date() 把字符转换成日期 Date 类型
format() 把日期显示成指定样式 字符型

例如:

date2 <- as.Date("2024-03-01", format = "%Y-%m-%d")
date2
[1] "2024-03-01"
class(date2)
[1] "Date"

可以看到,date2 是 Date 类型。

再使用 format()

date3 <- format(date2, "%Y年%m月%d日")
date3
[1] "2024年03月01日"
class(date3)
[1] "character"

可以看到,date3 变成了字符型。

所以要注意:

format() 主要用于改变显示格式,不适合继续做日期计算。

如果后面还要进行日期计算,建议保留 Date 类型。


4.7 常见日期格式示例

下面是一些常见写法。

as.Date("2024-03-01", format = "%Y-%m-%d")
[1] "2024-03-01"
as.Date("2024/03/01", format = "%Y/%m/%d")
[1] "2024-03-01"
as.Date("03/01/2024", format = "%m/%d/%Y")
[1] "2024-03-01"
as.Date("01/03/2024", format = "%d/%m/%Y")
[1] "2024-03-01"
as.Date("24-03-01", format = "%y-%m-%d")
[1] "2024-03-01"

对应关系如下:

原始日期 格式写法 含义
"2024-03-01" "%Y-%m-%d" 年-月-日
"2024/03/01" "%Y/%m/%d" 年/月/日
"03/01/2024" "%m/%d/%Y" 月/日/年
"01/03/2024" "%d/%m/%Y" 日/月/年
"24-03-01" "%y-%m-%d" 两位年-月-日

4.8 在数据框中使用日期格式

假设数据中的日期是字符型。

df_date <- data.frame(
  id = 1:4,
  date = c("2024-03-01", "2024-03-02", "2024-03-03", "2024-03-04")
)

df_date
  id       date
1  1 2024-03-01
2  2 2024-03-02
3  3 2024-03-03
4  4 2024-03-04
str(df_date)
'data.frame':   4 obs. of  2 variables:
 $ id  : int  1 2 3 4
 $ date: chr  "2024-03-01" "2024-03-02" "2024-03-03" "2024-03-04"

date 转换为日期型:

df_date <- df_date %>%
  mutate(
    date = as.Date(date, format = "%Y-%m-%d")
  )

df_date
  id       date
1  1 2024-03-01
2  2 2024-03-02
3  3 2024-03-03
4  4 2024-03-04
str(df_date)
'data.frame':   4 obs. of  2 variables:
 $ id  : int  1 2 3 4
 $ date: Date, format: "2024-03-01" "2024-03-02" ...

如果想生成一个“年月”变量,可以使用 format()

df_date <- df_date %>%
  mutate(
    year_month = format(date, "%Y-%m")
  )

df_date
  id       date year_month
1  1 2024-03-01    2024-03
2  2 2024-03-02    2024-03
3  3 2024-03-03    2024-03
4  4 2024-03-04    2024-03

这里的 year_month 是字符型,适合用于分组统计或标签显示。

例如按年月计数:

df_date %>%
  group_by(year_month) %>%
  summarise(
    count = n(),
    .groups = "drop"
  )
# A tibble: 1 × 2
  year_month count
  <chr>      <int>
1 2024-03        4

5. 因子基础

5.1 什么是因子?

因子是 R 中专门用来表示分类变量的数据类型。

例如:

  • 地区:华东、华北、华南;
  • 类别:食品、服装、电子;
  • 等级:低、中、高;
  • 性别:男、女。

简单来说:

因子就是有类别的数据。


5.2 字符变量转为因子

regioncategory 转换为因子。

sales <- sales %>%
  mutate(
    region = factor(region),
    category = factor(category)
  )

str(sales)
'data.frame':   8 obs. of  6 variables:
 $ id      : int  1 2 3 4 5 6 7 8
 $ date    : chr  "2024-01-05" "2024-01-12" "2024-02-03" "2024-02-20" ...
 $ region  : Factor w/ 3 levels "华北","华东",..: 2 1 3 2 1 3 2 1
 $ category: Factor w/ 3 levels "电子","服装",..: 3 2 1 3 2 1 3 2
 $ price   : num  20 150 3000 35 180 2500 28 220
 $ quantity: num  5 2 1 6 3 1 4 2

查看因子的类别:

levels(sales$region)
[1] "华北" "华东" "华南"
levels(sales$category)
[1] "电子" "服装" "食品"

5.3 设置因子的显示顺序

有时候我们希望分类变量按照指定顺序显示。

例如地区按照:

华东、华北、华南

显示。

sales <- sales %>%
  mutate(
    region = factor(
      region,
      levels = c("华东", "华北", "华南")
    )
  )

levels(sales$region)
[1] "华东" "华北" "华南"

因子的顺序会影响表格、绘图和模型中的显示顺序。


5.4 有序因子

有些分类变量本身有顺序,例如:

低、中、高

这种变量可以设置成有序因子。

下面根据价格创建价格等级。

sales <- sales %>%
  mutate(
    price_level = case_when(
      price < 100 ~ "低价",
      price < 1000 ~ "中价",
      TRUE ~ "高价"
    ),
    price_level = factor(
      price_level,
      levels = c("低价", "中价", "高价"),
      ordered = TRUE
    )
  )

sales
  id       date region category price quantity price_level
1  1 2024-01-05   华东     食品    20        5        低价
2  2 2024-01-12   华北     服装   150        2        中价
3  3 2024-02-03   华南     电子  3000        1        高价
4  4 2024-02-20   华东     食品    35        6        低价
5  5 2024-03-01   华北     服装   180        3        中价
6  6 2024-03-15   华南     电子  2500        1        高价
7  7 2024-04-02   华东     食品    28        4        低价
8  8 2024-04-18   华北     服装   220        2        中价

解释:

  • case_when() 用来根据条件创建分类变量;
  • factor(..., ordered = TRUE) 表示这是有顺序的因子。

6. 数据排序基础

6.1 按一个变量升序排序

使用 arrange() 可以排序。

例如,按照价格从小到大排序:

sales %>%
  arrange(price)
  id       date region category price quantity price_level
1  1 2024-01-05   华东     食品    20        5        低价
2  7 2024-04-02   华东     食品    28        4        低价
3  4 2024-02-20   华东     食品    35        6        低价
4  2 2024-01-12   华北     服装   150        2        中价
5  5 2024-03-01   华北     服装   180        3        中价
6  8 2024-04-18   华北     服装   220        2        中价
7  6 2024-03-15   华南     电子  2500        1        高价
8  3 2024-02-03   华南     电子  3000        1        高价

6.2 按一个变量降序排序

如果想从大到小排序,可以使用 desc()

sales %>%
  arrange(desc(price))
  id       date region category price quantity price_level
1  3 2024-02-03   华南     电子  3000        1        高价
2  6 2024-03-15   华南     电子  2500        1        高价
3  8 2024-04-18   华北     服装   220        2        中价
4  5 2024-03-01   华北     服装   180        3        中价
5  2 2024-01-12   华北     服装   150        2        中价
6  4 2024-02-20   华东     食品    35        6        低价
7  7 2024-04-02   华东     食品    28        4        低价
8  1 2024-01-05   华东     食品    20        5        低价

6.3 按多个变量排序

例如先按地区排序,再按价格从高到低排序。

sales %>%
  arrange(region, desc(price))
  id       date region category price quantity price_level
1  4 2024-02-20   华东     食品    35        6        低价
2  7 2024-04-02   华东     食品    28        4        低价
3  1 2024-01-05   华东     食品    20        5        低价
4  8 2024-04-18   华北     服装   220        2        中价
5  5 2024-03-01   华北     服装   180        3        中价
6  2 2024-01-12   华北     服装   150        2        中价
7  3 2024-02-03   华南     电子  3000        1        高价
8  6 2024-03-15   华南     电子  2500        1        高价

解释:

  • 先按照 region 排序;
  • 同一个地区内部,再按照 price 从大到小排序。

7. 计算变量

7.1 什么是计算变量?

计算变量就是根据已有变量生成新变量。

例如已有:

  • 单价 price
  • 数量 quantity

可以计算:

销售额 = 单价 × 数量

7.2 使用 mutate() 创建新变量

sales <- sales %>%
  mutate(
    amount = price * quantity
  )

sales
  id       date region category price quantity price_level amount
1  1 2024-01-05   华东     食品    20        5        低价    100
2  2 2024-01-12   华北     服装   150        2        中价    300
3  3 2024-02-03   华南     电子  3000        1        高价   3000
4  4 2024-02-20   华东     食品    35        6        低价    210
5  5 2024-03-01   华北     服装   180        3        中价    540
6  6 2024-03-15   华南     电子  2500        1        高价   2500
7  7 2024-04-02   华东     食品    28        4        低价    112
8  8 2024-04-18   华北     服装   220        2        中价    440

这里:

amount = price * quantity

表示新建一个变量 amount,它等于单价乘以数量。


7.3 一次创建多个新变量

例如继续计算折扣后金额。

sales <- sales %>%
  mutate(
    amount = price * quantity,
    discount_amount = amount * 0.9
  )

sales
  id       date region category price quantity price_level amount
1  1 2024-01-05   华东     食品    20        5        低价    100
2  2 2024-01-12   华北     服装   150        2        中价    300
3  3 2024-02-03   华南     电子  3000        1        高价   3000
4  4 2024-02-20   华东     食品    35        6        低价    210
5  5 2024-03-01   华北     服装   180        3        中价    540
6  6 2024-03-15   华南     电子  2500        1        高价   2500
7  7 2024-04-02   华东     食品    28        4        低价    112
8  8 2024-04-18   华北     服装   220        2        中价    440
  discount_amount
1            90.0
2           270.0
3          2700.0
4           189.0
5           486.0
6          2250.0
7           100.8
8           396.0

解释:

  • amount 是原始销售额;
  • discount_amount 是打 9 折后的销售额。

8. 条件变量

8.1 使用 ifelse() 创建二分类变量

如果只有两个类别,可以使用 ifelse()

例如,根据销售额判断是否为大订单。

sales <- sales %>%
  mutate(
    big_order = ifelse(amount >= 1000, "大订单", "普通订单")
  )

sales
  id       date region category price quantity price_level amount
1  1 2024-01-05   华东     食品    20        5        低价    100
2  2 2024-01-12   华北     服装   150        2        中价    300
3  3 2024-02-03   华南     电子  3000        1        高价   3000
4  4 2024-02-20   华东     食品    35        6        低价    210
5  5 2024-03-01   华北     服装   180        3        中价    540
6  6 2024-03-15   华南     电子  2500        1        高价   2500
7  7 2024-04-02   华东     食品    28        4        低价    112
8  8 2024-04-18   华北     服装   220        2        中价    440
  discount_amount big_order
1            90.0  普通订单
2           270.0  普通订单
3          2700.0    大订单
4           189.0  普通订单
5           486.0  普通订单
6          2250.0    大订单
7           100.8  普通订单
8           396.0  普通订单

解释:

ifelse(条件, 条件成立时的结果, 条件不成立时的结果)

8.2 使用 case_when() 创建多分类变量

如果有多个条件,推荐使用 case_when()

例如,把销售额分成低、中、高三类。

sales <- sales %>%
  mutate(
    amount_level = case_when(
      amount < 500 ~ "低销售额",
      amount < 2000 ~ "中销售额",
      TRUE ~ "高销售额"
    )
  )

sales
  id       date region category price quantity price_level amount
1  1 2024-01-05   华东     食品    20        5        低价    100
2  2 2024-01-12   华北     服装   150        2        中价    300
3  3 2024-02-03   华南     电子  3000        1        高价   3000
4  4 2024-02-20   华东     食品    35        6        低价    210
5  5 2024-03-01   华北     服装   180        3        中价    540
6  6 2024-03-15   华南     电子  2500        1        高价   2500
7  7 2024-04-02   华东     食品    28        4        低价    112
8  8 2024-04-18   华北     服装   220        2        中价    440
  discount_amount big_order amount_level
1            90.0  普通订单     低销售额
2           270.0  普通订单     低销售额
3          2700.0    大订单     高销售额
4           189.0  普通订单     低销售额
5           486.0  普通订单     中销售额
6          2250.0    大订单     高销售额
7           100.8  普通订单     低销售额
8           396.0  普通订单     低销售额

解释:

  • amount < 500 ~ "低销售额" 表示销售额小于 500;
  • amount < 2000 ~ "中销售额" 表示销售额小于 2000;
  • TRUE ~ "高销售额" 表示其他情况。

注意:

case_when() 会按照从上到下的顺序判断条件。


9. 分组汇总入门

9.1 什么是分组汇总?

分组汇总就是按照某个分类变量分组,然后计算每组的统计量。

例如:

  • 每个地区的总销售额;
  • 每个类别的平均价格;
  • 每个地区有多少订单。

9.2 按地区计算总销售额

sales %>%
  group_by(region) %>%
  summarise(
    total_amount = sum(amount),
    .groups = "drop"
  )
# A tibble: 3 × 2
  region total_amount
  <fct>         <dbl>
1 华东            422
2 华北           1280
3 华南           5500

解释:

  • group_by(region) 表示按地区分组;
  • sum(amount) 表示计算每个地区的销售额总和;
  • .groups = "drop" 表示汇总后取消分组。

9.3 按地区计算订单数和平均销售额

sales %>%
  group_by(region) %>%
  summarise(
    order_count = n(),
    avg_amount = mean(amount),
    .groups = "drop"
  )
# A tibble: 3 × 3
  region order_count avg_amount
  <fct>        <int>      <dbl>
1 华东             3       141.
2 华北             3       427.
3 华南             2      2750 

解释:

函数 作用
n() 计算每组有多少行
mean() 计算平均值
sum() 计算总和
max() 计算最大值
min() 计算最小值

10. 本节核心函数总结

本节最常用函数如下:

函数 作用
ymd() 把字符转换成日期
year() 提取年份
month() 提取月份
day() 提取日期中的日
wday() 提取星期
factor() 创建因子
levels() 查看因子水平
arrange() 排序
desc() 降序
mutate() 创建或修改变量
ifelse() 创建二分类变量
case_when() 创建多分类变量
group_by() 分组
summarise() 汇总

常用模板:

# 日期转换
df$date <- ymd(df$date)

# 提取月份
df <- df %>%
  mutate(month = month(date))

# 创建因子
df <- df %>%
  mutate(group = factor(group))

# 设置因子顺序
df <- df %>%
  mutate(
    level = factor(
      level,
      levels = c("低", "中", "高"),
      ordered = TRUE
    )
  )

# 排序
df %>%
  arrange(desc(x))

# 计算新变量
df <- df %>%
  mutate(new_var = x + y)

# 条件变量
df <- df %>%
  mutate(
    level = case_when(
      score >= 90 ~ "优秀",
      score >= 80 ~ "良好",
      TRUE ~ "继续努力"
    )
  )

# 分组汇总
df %>%
  group_by(group) %>%
  summarise(
    avg_x = mean(x),
    total_x = sum(x),
    n = n(),
    .groups = "drop"
  )

11. 小练习

下面只保留一个简单练习。

创建学生成绩数据:

student <- data.frame(
  id = 1:6,
  name = c("张三", "李四", "王五", "赵六", "钱七", "孙八"),
  class = c("一班", "二班", "一班", "三班", "二班", "三班"),
  exam_date = c(
    "2024-03-01", "2024-03-01", "2024-03-02",
    "2024-03-02", "2024-03-03", "2024-03-03"
  ),
  chinese = c(88, 76, 92, 85, 79, 90),
  math = c(90, 82, 88, 91, 75, 86),
  english = c(85, 78, 94, 87, 81, 89)
)

student
  id name class  exam_date chinese math english
1  1 张三  一班 2024-03-01      88   90      85
2  2 李四  二班 2024-03-01      76   82      78
3  3 王五  一班 2024-03-02      92   88      94
4  4 赵六  三班 2024-03-02      85   91      87
5  5 钱七  二班 2024-03-03      79   75      81
6  6 孙八  三班 2024-03-03      90   86      89

请完成:

  1. exam_date 转换成日期;
  2. 提取考试月份;
  3. class 转换为因子,并设置顺序为一班、二班、三班;
  4. 计算总分 total 和平均分 average
  5. 按平均分从高到低排序;
  6. 按班级计算平均分。

12. 小练习参考答案

student <- student %>%
  mutate(
    exam_date = ymd(exam_date),
    exam_month = month(exam_date),
    class = factor(
      class,
      levels = c("一班", "二班", "三班")
    ),
    total = chinese + math + english,
    average = round(total / 3, 1)
  )

student
  id name class  exam_date chinese math english exam_month total average
1  1 张三  一班 2024-03-01      88   90      85          3   263    87.7
2  2 李四  二班 2024-03-01      76   82      78          3   236    78.7
3  3 王五  一班 2024-03-02      92   88      94          3   274    91.3
4  4 赵六  三班 2024-03-02      85   91      87          3   263    87.7
5  5 钱七  二班 2024-03-03      79   75      81          3   235    78.3
6  6 孙八  三班 2024-03-03      90   86      89          3   265    88.3

按平均分从高到低排序:

student %>%
  arrange(desc(average))
  id name class  exam_date chinese math english exam_month total average
1  3 王五  一班 2024-03-02      92   88      94          3   274    91.3
2  6 孙八  三班 2024-03-03      90   86      89          3   265    88.3
3  1 张三  一班 2024-03-01      88   90      85          3   263    87.7
4  4 赵六  三班 2024-03-02      85   91      87          3   263    87.7
5  2 李四  二班 2024-03-01      76   82      78          3   236    78.7
6  5 钱七  二班 2024-03-03      79   75      81          3   235    78.3

按班级计算平均分:

student %>%
  group_by(class) %>%
  summarise(
    avg_score = mean(average),
    student_count = n(),
    .groups = "drop"
  )
# A tibble: 3 × 3
  class avg_score student_count
  <fct>     <dbl>         <int>
1 一班       89.5             2
2 二班       78.5             2
3 三班       88               2

13. 一句话总结

本节可以记住下面这几个函数:

ymd()
factor()
arrange()
mutate()
case_when()
group_by()
summarise()

其中:

  • ymd() 用来处理日期;
  • factor() 用来处理分类变量;
  • arrange() 用来排序;
  • mutate() 用来计算新变量;
  • case_when() 用来根据条件分类;
  • group_by()summarise() 用来分组汇总。