tidyverse自学笔记-长宽数据转换

数据准备
本示例数据是自编数据,仅为练习所用,数据结构假设为,两个年份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

参考资料

  1. R语言编程—基于 tidyverse,人民邮电出版社(待出版),2022.
  2. R语言教程,李东风,https://www.math.pku.edu.cn/teachers/lidf/docs/Rbook/html/_Rbook/index.html
  3. 用tidyr包进行长数据和宽数据的相互转换,https://www.jianshu.com/p/46a53717d964
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容