数据准备
本示例数据是自编数据,仅为练习所用,数据结构假设为,两个年份year(2020,2021),两个氮水平nitrogen(N1,N2),两个玉米品种variety(a,b)测定了5个试验指标(变量v1,v2,v3,v4,v5),每个处理3次重复block(1,2,3)。
library(tidyverse) # 调用tidyverse。
df <- read_csv(file = "df.csv") # 导入数据。文档在工作目录下,所以直接给文件名导入。
df # 查看数据。
## # A tibble: 24 x 9
## year nitrogen variety block v1 v2 v3 v4 v5
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2020 N1 a 1 1.26 2.14 0.4 5 3.25
## 2 2020 N1 a 2 1.2 2.9 0.1 5.3 1.27
## 3 2020 N1 a 3 1.3 3 0.3 5.6 2.24
## 4 2020 N1 b 1 1.08 1.72 1.8 2.8 1
## 5 2020 N1 b 2 1.05 1.65 1.7 2.5 3.12
## 6 2020 N1 b 3 1.15 1.35 1.5 3.1 4.57
## 7 2020 N2 a 1 1.32 3.78 1.6 6 5.85
## 8 2020 N2 a 2 1.28 4.32 1.4 6.1 6.48
## 9 2020 N2 a 3 1.35 3.95 1.3 6.2 7.21
## 10 2020 N2 b 1 1.33 3.47 2.8 4.1 6.56
## # ... with 14 more rows
5. 数据重塑
5.1 认识长宽数据
宽数据:每一行代表一个观测,每一列表示所观测到的变量。但是同一变量的多个水平的观测出现在多个列中。如下例子中N1和N2分别占了一列。最终数据呈现为变量多,观测少。
widerdata <- tibble(year = c("2020", "2021", "2022"),N1 = c(100, 120, 110), N2 = c(200, 240, 260)) # 宽数据。
widerdata # 返回数据。
## # A tibble: 3 x 3
## year N1 N2
## <chr> <dbl> <dbl>
## 1 2020 100 200
## 2 2021 120 240
## 3 2022 110 260
长数据:每一行代表一个观测,每一列表示所观测到的变量。变量的多个水平的观测出现在同一列中。如例子中N1和N2的观测值在同一列。最终数据呈现为变量少,观测多。
longerdata <- tibble(year = rep(c("2020", "2021", "2022"),each = 2),nitrogen = rep(c("N1", "N2"), 3),产量 = c(100, 200, 120, 240, 110, 260)) # 长数据。
longerdata # 返回长数据。
## # A tibble: 6 x 3
## year nitrogen 产量
## <chr> <chr> <dbl>
## 1 2020 N1 100
## 2 2020 N2 200
## 3 2021 N1 120
## 4 2021 N2 240
## 5 2022 N1 110
## 6 2022 N2 260
整洁数据:
Each variable forms a column. 每个变量一列。
Each observation forms a row. 每个观测一行。
Each type of observational unit forms a table. 每种类型的观测单元一张表。
5.2 长宽数据转换
5.2.1 reshape2包
在reshape2包中melt可完成数据的宽格式向长格式的转化。
宽转长
melt(data,
id.vars,
measure.vars,
variable.name = "variable",
...,
na.rm = FALSE,
value.name = "value",
factorsAsStrings = TRUE)
参数详解:
- data:要变换的数据框。
- id.vars:不需要进行melt的列名,通常会随着melt不停重复堆叠,因此最好为无数学意义整数(变量位置信息)或字符串(名称信息)。
- measure.vars:观测值列名。
- variable.name:melt 后观测变量的列名 ,不填默认为 variable。
- value.name:melt 后观测值的列名, 不填默认为 value。
library(reshape2) # 调用reshape2包。
melt(widerdata, id.vars = "year", variable.name = "nitrogen", value.name = "产量") # melt函数进行宽变长。
## year nitrogen 产量
## 1 2020 N1 100
## 2 2021 N1 120
## 3 2022 N1 110
## 4 2020 N2 200
## 5 2021 N2 240
## 6 2022 N2 260
长转宽
dcast(data,
formula,
fun.aggregate = NULL,
...,
margins = NULL,
subset = NULL,
fill = NULL,
drop = TRUE,
value.var = guess_value(data))
参数详解:
- data:要变换的数据框。
- formula:形如x ~ y,x为行标签,y为列标签。
- fun.aggregate:聚合函数,对value值进行处理。
- margins:是否加上边际值。
- subset:对结果进行条件筛选。
- drop:是否保留缺失值。
- value.var:后面跟要处理的字段。
dcast(longerdata, year ~ nitrogen) # 长数据转宽数据。
## year N1 N2
## 1 2020 100 200
## 2 2021 120 240
## 3 2022 110 260
5.2.2 tidyr包
宽变长
pivot_longer()函数
pivot_longer(
data,
cols,
names_to = "name",
names_prefix = NULL,
names_sep = NULL,
names_pattern = NULL,
names_ptypes = NULL,
names_transform = NULL,
names_repair = "check_unique",
values_to = "value",
values_drop_na = FALSE,
values_ptypes = NULL,
values_transform = NULL,
...)
参数详解:
- data:要变换的数据框。
- cols:要变换的列的选择,通过选择列语法选择。
- names_to:指定存放变换列的新列名。
- values_to:指定存放变换列值的列名称。
- values_drop_na = FALSE:逻辑变量,是否忽略变换列中的NA。
longerdata <- widerdata %>% pivot_longer(-year, names_to = "nitrogen",values_to = "产量") # 宽变长。
longerdata # 返回长数据结果。
## # A tibble: 6 x 3
## year nitrogen 产量
## <chr> <chr> <dbl>
## 1 2020 N1 100
## 2 2020 N2 200
## 3 2021 N1 120
## 4 2021 N2 240
## 5 2022 N1 110
## 6 2022 N2 260
长变宽
pivot_wider()函数,pivot_longer()的反向操作。
pivot_wider(
data,
id_cols = NULL,
id_expand = FALSE,
names_from = name,
names_prefix = "",
names_sep = "_",
names_glue = NULL,
names_sort = FALSE,
names_vary = "fastest",
names_expand = FALSE,
names_repair = "check_unique",
values_from = value,
values_fill = NULL,
values_fn = NULL,
unused_fn = NULL,
...)
参数详解:
- data:要变换的数据框。
- id_cols:唯一识别观测的列,默认是除了names_from和values_from指定列之外的列。
- names_from:指定列名来自哪个变量列。
- values_from:指定列值来自哪个变量列。
- values_fill:若变宽后单元格缺失,设置用何值填充。
longerdata %>% pivot_wider(names_from = nitrogen, values_from = "产量", values_fill = 0) # 长数据变宽数据。
## # A tibble: 3 x 3
## year N1 N2
## <chr> <dbl> <dbl>
## 1 2020 100 200
## 2 2021 120 240
## 3 2022 110 260
参考资料
- R语言编程—基于 tidyverse,人民邮电出版社(待出版),2022.
- R语言教程,李东风,https://www.math.pku.edu.cn/teachers/lidf/docs/Rbook/html/_Rbook/index.html
- 用tidyr包进行长数据和宽数据的相互转换,https://www.jianshu.com/p/46a53717d964