R-切割数据

1.cut

cut() 函数用于将连续型数据离散为离散的区间(分组),常用于将数值变量转换为分类变量(如将年龄分为 "儿童""青年""中年""老年")。

R 复制代码
cut(x, breaks, labels = NULL, include.lowest = FALSE, right = TRUE, ...)

参数说明

  • x:需要分箱的连续型向量(数值向量)。
  • breaks :指定分组的分割点,可以是:
    • 整数:表示将 x 等分为 breaks 个区间;
    • 数值向量:直接指定分割点(如 c(0, 10, 20, 30) 表示按 0、10、20、30 分割)。
  • labels:为每个区间指定标签(字符向量),长度需与区间数量一致。
  • include.lowest :逻辑值(默认 FALSE),若为 TRUE,则包含区间的最小值(避免最小值被遗漏)。
  • right :逻辑值(默认 TRUE),若为 TRUE,区间为右闭左开(如 (10, 20]);若为 FALSE,则为左闭右开(如 [10, 20))。

1.2.示例

R 复制代码
scores <- c(85, 92, 78, 65, 58, 90, 88, 76)
score_groups <- cut(
  x = scores,
  breaks = c(0, 60, 80, 100),  # 分割点:0-60、60-80、80-100
  labels = c("不及格", "良好", "优秀"),  # 区间标签
  include.lowest = TRUE  # 包含最小值(0),确保 60 分被划入"良好"
)
print(score_groups)
#[1] 优秀   优秀   良好   良好   不及格 优秀   优秀   良好  
#Levels: 不及格 良好 优秀
#结果是一个因子

#等距分箱
ages <- c(22, 18, 35, 42, 58, 29, 65, 48)
age_groups <- cut(ages, breaks = 3)
print(age_groups)
#[1] (18,33.7]   (18,33.7]   (33.7,49.3] (33.7,49.3] (49.3,65]   (18,33.7]   (49.3,65]   (33.7,49.3]
#Levels: (18,33.7] (33.7,49.3] (49.3,65]

#right参数
x <- c(10,20,30)
cut(x,breaks = c(10,20,30),right = TRUE )
cut(x,breaks = c(10,20,30),right = FALSE)
#[1] <NA>    (10,20] (20,30]
#Levels: (10,20] (20,30]
#[1] [10,20) [20,30) <NA>   
#Levels: [10,20) [20,30)

1.3.应用场景

数据离散化:将连续变量(如收入、成绩)转换为分类变量,便于分组分析。

创建分组标签:为可视化(如直方图、箱线图)或建模(如逻辑回归)提供分类依据。

分位数分组 :结合 quantile() 按分位数分割(如四分位数、五分位数):

1.4.注意事项

缺失值处理 :不在 breaks 范围内的值会被标记为 NA(缺失),需通过 include.lowest 等参数避免。

因子输出cut() 返回的是因子类型,若需字符型,可加 as.character() 转换。

分割点顺序breaks 必须是递增的数值向量,否则会报错。

2.Hmisc::cut2

2.1语法

R 复制代码
cut2(x, cuts, m, g, levels.mean = FALSE, digits, ...)

主要参数说明:

  • x:需要分箱的连续型向量(数值向量)。
  • cuts :自定义分割点(类似基础 cut()breaks),如 c(0, 50, 100)
  • m :每个区间至少包含的观测值数量(优先级高于 g)。
  • g:指定分组数量(等频分组,即按分位数大致均分数据)。
  • levels.mean :逻辑值(默认 FALSE),若为 TRUE,则用区间均值作为标签,而非区间范围。
  • digits:区间标签的小数位数(控制显示精度)。

2.2与cut区别

等频分组更便捷 :通过 g 参数直接指定分组数,自动按分位数划分(每组数量大致相等)。

控制最小样本量m 参数确保每个区间至少有 m 个观测值,避免区间包含样本太少。

标签更友好:默认标签格式更简洁,且支持用均值作为标签。

2.3示例

2.3.1等频分组,g参数

R 复制代码
library(Hmisc)

set.seed(123)
x <- rnorm(100, mean = 50, sd = 10)
print(x)
# 等频分组
groups <- Hmisc::cut2(x, g = 4)
print(groups)
# 查看分组结果及每组数量
table(groups)

> print(groups)
  [1] [26.9,45.1) [45.1,50.7) [57.0,71.9] [50.7,57.0) [50.7,57.0) [57.0,71.9] [50.7,57.0) [26.9,45.1) [26.9,45.1)
 [10] [45.1,50.7) [57.0,71.9] [50.7,57.0) [50.7,57.0) [50.7,57.0) [26.9,45.1) [57.0,71.9] [50.7,57.0) [26.9,45.1)
 [19] [57.0,71.9] [45.1,50.7) [26.9,45.1) [45.1,50.7) [26.9,45.1) [26.9,45.1) [26.9,45.1) [26.9,45.1) [57.0,71.9]
 [28] [50.7,57.0) [26.9,45.1) [57.0,71.9] [50.7,57.0) [45.1,50.7) [57.0,71.9] [57.0,71.9] [57.0,71.9] [50.7,57.0)
 [37] [50.7,57.0) [45.1,50.7) [45.1,50.7) [45.1,50.7) [26.9,45.1) [45.1,50.7) [26.9,45.1) [57.0,71.9] [57.0,71.9]
 [46] [26.9,45.1) [45.1,50.7) [45.1,50.7) [57.0,71.9] [45.1,50.7) [50.7,57.0) [45.1,50.7) [45.1,50.7) [57.0,71.9]
 [55] [45.1,50.7) [57.0,71.9] [26.9,45.1) [50.7,57.0) [50.7,57.0) [50.7,57.0) [50.7,57.0) [26.9,45.1) [45.1,50.7)
 [64] [26.9,45.1) [26.9,45.1) [50.7,57.0) [50.7,57.0) [45.1,50.7) [57.0,71.9] [57.0,71.9] [45.1,50.7) [26.9,45.1)
 [73] [57.0,71.9] [26.9,45.1) [26.9,45.1) [57.0,71.9] [45.1,50.7) [26.9,45.1) [50.7,57.0) [45.1,50.7) [45.1,50.7)
 [82] [50.7,57.0) [45.1,50.7) [50.7,57.0) [45.1,50.7) [50.7,57.0) [57.0,71.9] [50.7,57.0) [45.1,50.7) [57.0,71.9]
 [91] [57.0,71.9] [50.7,57.0) [50.7,57.0) [26.9,45.1) [57.0,71.9] [26.9,45.1) [57.0,71.9] [57.0,71.9] [45.1,50.7)
[100] [26.9,45.1)
Levels: [26.9,45.1) [45.1,50.7) [50.7,57.0) [57.0,71.9]

> table(groups)
groups
[26.9,45.1) [45.1,50.7) [50.7,57.0) [57.0,71.9] 
         25          25          25          25

2.3.2控制每组最小样本量,m参数

R 复制代码
# 确保每个区间至少有10个观测值
groups_m <- cut2(x, m = 10)
table(groups_m)
> table(groups_m)
groups_m
[26.9,39.3) [39.3,43.7) [43.7,46.2) [46.2,47.8) [47.8,50.7) [50.7,53.3) [53.3,55.5) [55.5,59.0) [59.0,63.6) [63.6,71.9] 
         10          10          10          10          10          10          10          10          10          10 

2.3.3自定义分割点,cuts参数

R 复制代码
# 按自定义分割点分箱
groups_cuts <- cut2(x, cuts = c(40, 50, 60))
table(groups_cuts)
groups_cuts
[26.9,40.0) [40.0,50.0) [50.0,60.0) [60.0,71.9] 
         14          34          35          17

2.3.4用区间均值作为标签,levels.mean = TRUE

R 复制代码
# 分组后用均值作为标签(而非区间范围)
groups_mean <- cut2(x, g = 4, levels.mean = TRUE, digits = 1)
table(groups_mean)
> table(groups_mean)
groups_mean
40 48 54 63 
25 25 25 25 

2.3.总结

等频分组更智能g 参数自动按分位数划分,避免基础 cut() 按等距划分可能导致的组内样本量不均。

灵活控制分组粒度m 参数确保每组有足够样本,适合小样本数据。

标签更实用:支持均值标签,便于后续分析和可视化。

3.重塑数据

"熔化(melt)" 和 "铸造(cast)" 是重塑数据的两种核心操作,主要用于将数据在宽格式(wide format)长格式(long format) 之间转换。这两种操作在 reshape2reshape 包中实现,是数据处理和可视化(如 ggplot2)的重要基础。

3.1基本概念:宽格式和长格式

宽格式:每行代表一个观测单元,每列代表一个变量,(同一属性的不同类别分散在多列中),属性类别通常直接对应列名。宽格式中每一列代表同一属性的不同类别,或者不同属性的度量值。

如:

R 复制代码
ID  2020  2021  2022
A   100   150   200
B   120   180   220

2020,2021,2022都是年份这个属性的不同类别,而每行A和B是观测的对象(可以看成另一个属性),然后每个值,就是该对象对应某年的度量值。

长格式:每行代表一个观测单元的某个属性值,用额外的列标记属性类别(同一属性的不同类别集中在一列中)。

R 复制代码
ID  year  sales
A   2020   100
A   2021   150
A   2022   200
B   2020   120
B   2021   180
B   2022   220

3.1.1总结

宽格式 :属性的不同类别以列名形式存在,每列对应一个具体类别;

长格式 :属性的所有类别集中在同一列中,用该列的值来区分不同类别。

3.2熔化(melt)从宽格式->长格式

"熔化" 是将宽格式数据转换为长格式,保留标识变量(id variables),将其他变量 "堆叠" 为 "属性 - 值" 对(即新增 "变量名" 和 "变量值" 两列)。

3.2.1语法reshape2::melt()

R 复制代码
melt(data, id.vars, measure.vars, variable.name = "variable", value.name = "value")
  • data:要转换的数据框。
  • id.vars:标识变量(保持不变的列,如示例中的 ID)。
  • measure.vars:要被 "熔化" 的变量(需要堆叠的列,如示例中的 2020/2021/2022)。
  • variable.name:新增的 "属性类别" 列的名称(默认 variable)。
  • value.name:新增的 "属性值" 列的名称(默认 value)。

3.2.2示例

R 复制代码
library(reshape2)
head(mtcars,2)
mtcars$carName <- rownames(mtcars)
head(mtcars)
carMelt <- melt(mtcars,id.vars = c('carName','gear','cyl'),measure.vars = c('mpg','hp'))
head(carMelt,3)
print(carMelt)

> head(mtcars)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb           carName
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4         Mazda RX4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4     Mazda RX4 Wag
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1        Datsun 710
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1    Hornet 4 Drive
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2 Hornet Sportabout
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1           Valiant

> head(carMelt,3)
        carName gear cyl variable value
1     Mazda RX4    4   6      mpg  21.0
2 Mazda RX4 Wag    4   6      mpg  21.0
3    Datsun 710    4   4      mpg  22.8
> print(carMelt)
               carName gear cyl variable value
1            Mazda RX4    4   6      mpg  21.0
2        Mazda RX4 Wag    4   6      mpg  21.0
3           Datsun 710    4   4      mpg  22.8
4       Hornet 4 Drive    3   6      mpg  21.4
5    Hornet Sportabout    3   8      mpg  18.7
6              Valiant    3   6      mpg  18.1
7           Duster 360    3   8      mpg  14.3
8            Merc 240D    4   4      mpg  24.4
9             Merc 230    4   4      mpg  22.8
10            Merc 280    4   6      mpg  19.2
11           Merc 280C    4   6      mpg  17.8
12          Merc 450SE    3   8      mpg  16.4
13          Merc 450SL    3   8      mpg  17.3
14         Merc 450SLC    3   8      mpg  15.2
15  Cadillac Fleetwood    3   8      mpg  10.4
16 Lincoln Continental    3   8      mpg  10.4
17   Chrysler Imperial    3   8      mpg  14.7
18            Fiat 128    4   4      mpg  32.4
19         Honda Civic    4   4      mpg  30.4
20      Toyota Corolla    4   4      mpg  33.9
21       Toyota Corona    3   4      mpg  21.5
22    Dodge Challenger    3   8      mpg  15.5
23         AMC Javelin    3   8      mpg  15.2
24          Camaro Z28    3   8      mpg  13.3
25    Pontiac Firebird    3   8      mpg  19.2
26           Fiat X1-9    4   4      mpg  27.3
27       Porsche 914-2    5   4      mpg  26.0
28        Lotus Europa    5   4      mpg  30.4
29      Ford Pantera L    5   8      mpg  15.8
30        Ferrari Dino    5   6      mpg  19.7
31       Maserati Bora    5   8      mpg  15.0
32          Volvo 142E    4   4      mpg  21.4
33           Mazda RX4    4   6       hp 110.0
34       Mazda RX4 Wag    4   6       hp 110.0
35          Datsun 710    4   4       hp  93.0
36      Hornet 4 Drive    3   6       hp 110.0
37   Hornet Sportabout    3   8       hp 175.0
38             Valiant    3   6       hp 105.0
39          Duster 360    3   8       hp 245.0
40           Merc 240D    4   4       hp  62.0
41            Merc 230    4   4       hp  95.0
42            Merc 280    4   6       hp 123.0
43           Merc 280C    4   6       hp 123.0
44          Merc 450SE    3   8       hp 180.0
45          Merc 450SL    3   8       hp 180.0
46         Merc 450SLC    3   8       hp 180.0
47  Cadillac Fleetwood    3   8       hp 205.0
48 Lincoln Continental    3   8       hp 215.0
49   Chrysler Imperial    3   8       hp 230.0
50            Fiat 128    4   4       hp  66.0
51         Honda Civic    4   4       hp  52.0
52      Toyota Corolla    4   4       hp  65.0
53       Toyota Corona    3   4       hp  97.0
54    Dodge Challenger    3   8       hp 150.0
55         AMC Javelin    3   8       hp 150.0
56          Camaro Z28    3   8       hp 245.0
57    Pontiac Firebird    3   8       hp 175.0
58           Fiat X1-9    4   4       hp  66.0
59       Porsche 914-2    5   4       hp  91.0
60        Lotus Europa    5   4       hp 113.0
61      Ford Pantera L    5   8       hp 264.0
62        Ferrari Dino    5   6       hp 175.0
63       Maserati Bora    5   8       hp 335.0
64          Volvo 142E    4   4       hp 109.0

3.3铸造:从长格式->宽格式

"铸造" 是熔化的逆操作,将长格式数据转换回宽格式,通过指定 "行标识""列标识" 和 "值" 来重塑数据。

3.3.1. reshape2::dcast() 语法(用于数据框)

R 复制代码
dcast(data, formula, fun.aggregate = NULL, value.var)
  • data:长格式数据框。
  • formula:格式为 行标识 ~ 列标识(用 ~ 分隔,左侧是行分组,右侧是列分组)。
  • fun.aggregate:聚合函数(当存在多值对应同一位置时,如 sum/mean,默认不聚合)。
  • value.var:指定用于填充单元格的值所在的列(即长格式中的 "值列")。

3.3.2示例

R 复制代码
# 铸造
wide_data2 <- dcast(carMelt,cyl~variable,value.var = "value")
print(wide_data2)

Aggregation function missing: defaulting to length
> print(wide_data2)
  cyl mpg hp
1   4  11 11
2   6   7  7
3   8  14 14

报错:Aggregation function missing: defaulting to length

同一行和列的交叉位置存在多个值 ,但未指定如何聚合这些值,此时函数默认使用 length() 函数(统计值的数量)作为聚合方式。

R 复制代码
wide_data2 <- dcast(carMelt,cyl~variable,fun.aggregate = mean,value.var = "value")
print(wide_data2)
> print(wide_data2)
  cyl      mpg        hp
1   4 26.66364  82.63636
2   6 19.74286 122.28571
3   8 15.10000 209.21429

3.3.3 reshape2::acast() 基本语法

它的返回结果是数组(array) 或矩阵(matrix),而非数据框(data frame)。这使得它特别适合处理多维度(超过 2 维)的数据重塑,或需要矩阵 / 数组输出的场景。

R 复制代码
acast(data, formula, fun.aggregate = NULL, value.var = "value", ...)
参数说明:
  • data:长格式数据框(需要转换的数据)。
  • formula :重塑公式,格式为 行 ~ 列 ~ 维度3 ~ ...(用 ~ 分隔不同维度,支持 1 维、2 维或更高维)。
  • fun.aggregate :聚合函数(当同一交叉位置有多个值时使用,如 summean;默认无,若有重复值会报错,需显式指定)。
  • value.var :指定用于填充数组 / 矩阵的值所在的列(长格式中的 "值列",默认 value)。

3.3.4 acast示例

R 复制代码
wide_data3 <- acast(carMelt,cyl~gear~variable,value.var = "value")
print(wide_data3)
wide_data3 <- acast(carMelt,cyl~gear~variable,value.var = "value",fun.aggregate = mean)
print(wide_data3)

> print(wide_data3)
, , mpg

   3 4 5
4  1 8 2
6  2 4 1
8 12 0 2

, , hp

   3 4 5
4  1 8 2
6  2 4 1
8 12 0 2

> print(wide_data3)
, , mpg

      3      4    5
4 21.50 26.925 28.2
6 19.75 19.750 19.7
8 15.05    NaN 15.4

, , hp

         3     4     5
4  97.0000  76.0 102.0
6 107.5000 116.5 175.0
8 194.1667   NaN 299.5

3.3.5区别

函数 返回类型 适用场景 公式维度限制
dcast 数据框(data frame) 2 维数据重塑,需要保留行 / 列名称 最多 2 维(行~列)
acast 数组(array)/ 矩阵 1 维、2 维或更高维数据重塑,需矩阵 / 数组输出 支持任意维度(行~列~维度 3...)
相关推荐
哞哞不熬夜3 小时前
JavaEE--SpringIoC
java·开发语言·spring boot·spring·java-ee·maven
newxtc3 小时前
【猿辅导-注册安全分析报告-无验证方式导致安全隐患】
开发语言·selenium·安全·yolo·安全爆破
张人玉3 小时前
c#WPF基础知识
开发语言·c#·wpf
std78793 小时前
Rust 与 Go – 比较以及每个如何满足您的需求
开发语言·golang·rust
报错小能手3 小时前
python(入门)map内置函数及import模块导入,as别名
开发语言·人工智能·python
梵得儿SHI4 小时前
Java 反射机制实战:对象属性复制与私有方法调用全解析
java·开发语言·java反射机制的实际应用·对象属性复制·反射调用私有方法·私有字段·类型兼容性和敏感字段忽略
sulikey4 小时前
C++的STL:深入理解 C++ 的 std::initializer_list
开发语言·c++·stl·list·initializerlist·c++标准库
liu****4 小时前
19.map和set的封装
开发语言·数据结构·c++·算法
孤廖4 小时前
C++ 模板再升级:非类型参数、特化技巧(含全特化与偏特化)、分离编译破解
linux·服务器·开发语言·c++·人工智能·后端·深度学习