长宽数据格式简介
在数据科学中,数据通常以两种主要格式存在:宽格式和长格式。理解这两种数据格式对于有效地使用tidyr
包进行数据整理至关重要。
tidyr
包主要功能
tidyr
包是R语言中用于数据整理的一个重要工具,它提供了一组函数,用于在宽格式和长格式之间转换,以及处理缺失值和数据列分割合并。以下是一些关键函数及其用法:
数据宽长转换
pivot_longer()
宽变长
将数据从宽格式转换为长格式。此函数将多个列的值合并到两个列中:一个表示变量名称,另一个表示变量值。
用法:
scoresLong = scores %>%
pivot_longer(cols = -1,
names_to = "学科",
values_to = "成绩")
scoresLong
# A tibble: 9 x 3
学生 学科 成绩
<chr> <chr> <dbl>
1 小红 语文 NA
2 小红 数学 70
3 小红 英语 100
4 小明 语文 70
5 小明 数学 NA
6 小明 英语 80
7 小刚 语文 80
8 小刚 数学 78
9 小刚 英语 40
解释:
pivot_wider()
长变宽
将数据从长格式转换为宽格式。此函数将长格式数据中的一列转换为多个列。
用法:
scoresLong %>%
pivot_wider(names_from = `学科`,
values_from = `成绩`)
# A tibble: 3 x 4
学生 语文 数学 英语
<chr> <dbl> <dbl> <dbl>
1 小红 NA 70 100
2 小明 70 NA 80
3 小刚 80 78 40
解释:
names_from
: 用于创建新列的列。
values_from
: 用于填充新列的数据列。
分割合并列
separate()
分割列
将一列拆分为多个列,根据指定的分隔符。
用法:
scores = tibble(
"学生"=c("1班-小红","1班-小明","2班-小刚"),
"语文"=c(NA,70,80),
"数学"=c(70,NA,78),
"英语"=c(100,80,40)
)
scoresSep = scores %>%
separate(col = `学生`,
into = c("班级","姓名"),
sep="-")
scoresSep
# A tibble: 3 x 5
班级 姓名 语文 数学 英语
<chr> <chr> <dbl> <dbl> <dbl>
1 1班 小红 NA 70 100
2 1班 小明 70 NA 80
3 2班 小刚 80 78 40
unite()
合并列
将多个列合并为一列
用法:
# 将列,班级和姓名,合并成列 学生
scoresSep %>%
unite(`学生`,
`班级`,
`姓名`,
sep = "-")
# A tibble: 3 x 4
学生 语文 数学 英语
<chr> <dbl> <dbl> <dbl>
1 1班-小红 NA 70 100
2 1班-小明 70 NA 80
3 2班-小刚 80 78 40
补充:
separate_rows
分割列,并新增行。
tibble(
x = 1:3,
y = c("a", "d,e,f", "g,h")
) %>%
separate_rows(y,
sep=",")
# A tibble: 6 x 2
x y
<int> <chr>
1 1 a
2 2 d
3 2 e
4 2 f
5 3 g
6 3 h
处理缺失值
drop_na()
删除包含缺失值的行。
用法:
# 删除包含空值的行
scores %>%
drop_na()
# A tibble: 1 x 4
学生 语文 数学 英语
<chr> <dbl> <dbl> <dbl>
1 2班-小刚 80 78 40
# 删除语文列是空值的行
scores %>%
drop_na(`语文`)
# A tibble: 2 x 4
学生 语文 数学 英语
<chr> <dbl> <dbl> <dbl>
1 1班-小明 70 NA 80
2 2班-小刚 80 78 40
fill()
填补缺失值
可以按前向填充(down
)或后向填充(up
)。
用法:
scores %>%
fill(`数学`,
.direction ="down") # 填充方向down up downup updown
# A tibble: 3 x 4
学生 语文 数学 英语
<chr> <dbl> <dbl> <dbl>
1 1班-小红 NA 70 100
2 1班-小明 70 70 80
3 2班-小刚 80 78 40
replace_na()
替换缺失值
# 把语文列的NA替换成0
scores %>%
replace_na(list("语文"=0))
# A tibble: 3 x 4
学生 语文 数学 英语
<chr> <dbl> <dbl> <dbl>
1 1班-小红 0 70 100
2 1班-小明 70 NA 80
3 2班-小刚 80 78 40
补充:
将数据中所有的NA替换成0
# tidyverse写法
scores %>%
mutate(across(everything(), ~ replace_na(., 0)))
# A tibble: 3 x 4
学生 语文 数学 英语
<chr> <dbl> <dbl> <dbl>
1 1班-小红 0 70 100
2 1班-小明 70 0 80
3 2班-小刚 80 78 40
# base R 写法
scores[is.na(scores)] = 0
scores
# A tibble: 3 x 4
学生 语文 数学 英语
<chr> <dbl> <dbl> <dbl>
1 1班-小红 0 70 100
2 1班-小明 70 0 80
3 2班-小刚 80 78 40