关于tidyr
工具包已经有三篇推文了,详情可查看本号推文索引。本篇来介绍该包剩余的其他函数。
tidyr
工具包的功能是使数据更加整洁,多配合dplyr
工具包进行数据预处理,其包含的函数并不多,除已经介绍的三类函数外,其他函数列举如下。
library(tidyr)
变量取值组合
创建以下数据框作为示例数据:
df01 <- data.frame(x = c(1, 2, 3, 2),
y = c("B", "A", "C", "A"),
z = c("c", "b", "a", "b"))
df01
## x y z
## 1 1 B c
## 2 2 A b
## 3 3 C a
## 4 2 A b
df01
的三个变量的取值空间的长度都为3,每行表示它们之间的一种组合形式,并允许重复出现。
expand()
expand()
函数的功能是输出数据框中被选中变量之间所有的组合形式。它的语法结构如下:
expand(data, ..., .name_repair = "check_unique")
data:变量所在的数据框;
...:选中的变量名,数量不限;
使用expand()
函数可以输出所有的可能组合情况:
expand(df01, x, y)
## # A tibble: 9 x 2
## x y
## <dbl> <fct>
## 1 1 A
## 2 1 B
## 3 1 C
## 4 2 A
## 5 2 B
## 6 2 C
## 7 3 A
## 8 3 B
## 9 3 C
expand(df01, x, y, z)
## # A tibble: 27 x 3
## x y z
## <dbl> <fct> <fct>
## 1 1 A a
## 2 1 A b
## 3 1 A c
## 4 1 B a
## 5 1 B b
## 6 1 B c
## 7 1 C a
## 8 1 C b
## 9 1 C c
## 10 2 A a
## # ... with 17 more rows
expand.grid()
expand.grid()
是base
工具包中的一个函数,它在组合时会将变量各行的取值按行序依次组合,若有重复值则会出现多次。
expand.grid(df01$x, df01$y)
## Var1 Var2
## 1 1 B
## 2 2 B
## 3 3 B
## 4 2 B
## 5 1 A
## 6 2 A
## 7 3 A
## 8 2 A
## 9 1 C
## 10 2 C
## 11 3 C
## 12 2 C
## 13 1 A
## 14 2 A
## 15 3 A
## 16 2 A
各位读者可以尝试从以下几个方面对比
expand(df, x, y)
和expand.grid(df$x, df$y)
语句的不同:
语法形式;
输出对象的行数;组合形式是否有重复;
输出对象中变量取值的排序。
expand_grid()
expand_grid()
函数是tidyr
工具包中的函数,与expand.grid()
功能类似。区别在于输出对象中的数值型变量会按大小顺序排列。
expand_grid(df01$x, df01$y)
## # A tibble: 16 x 2
## `df01$x` `df01$y`
## <dbl> <fct>
## 1 1 B
## 2 1 A
## 3 1 C
## 4 1 A
## 5 2 B
## 6 2 A
## 7 2 C
## 8 2 A
## 9 3 B
## 10 3 A
## 11 3 C
## 12 3 A
## 13 2 B
## 14 2 A
## 15 2 C
## 16 2 A
crossing()
和nesting()
观察以下语句的输出结果:
crossing(df01$x, df01$y)
## # A tibble: 9 x 2
## `df01$x` `df01$y`
## <dbl> <fct>
## 1 1 A
## 2 1 B
## 3 1 C
## 4 2 A
## 5 2 B
## 6 2 C
## 7 3 A
## 8 3 B
## 9 3 C
nesting(df01$x, df01$y)
## # A tibble: 3 x 2
## `df01$x` `df01$y`
## <dbl> <fct>
## 1 1 B
## 2 2 A
## 3 3 C
crossing()
函数的语法结构与expand_grid()
函数类似,但是输出对象与expand()
函数类型,即会去除重复的组合形式;
nesting()
函数的输出对象仅包含数据中出现过的组合形式。
将nesting()
函数和expand()
函数连用,更符合tidyverse式的语法风格:
expand(df01, nesting(x, y))
## # A tibble: 3 x 2
## x y
## <dbl> <fct>
## 1 1 B
## 2 2 A
## 3 3 C
complete()
complete()
函数在保留原有数据框内容的前提下,会在数据框中添加选中变量之间未出现的组合形式,相应地未被选中的变量取值则记为缺失值NA
。
complete(df01, x, y)
## # A tibble: 10 x 3
## x y z
## <dbl> <fct> <fct>
## 1 1 A <NA>
## 2 1 B c
## 3 1 C <NA>
## 4 2 A b
## 5 2 A b
## 6 2 B <NA>
## 7 2 C <NA>
## 8 3 A <NA>
## 9 3 B <NA>
## 10 3 C a
可以看出,变量
z
取值不为NA的行是df
中原有的内容,取值为NA的行是新增的。
uncount()
该函数以一个或多个数值型变量为权重来重复对应行其他的变量组合,是dplyr
工具包count()
函数的反向操作函数。语法结构如下:
uncount(data, weights, .remove = TRUE,
.id = NULL)
data:数据框;
weights:权重变量组成的向量;
.remove:是否将权重变量从数据框中移除;默认为TRUE。
uncount(df01, x, .remove = F)
## x y z
## 1 1 B c
## 2 2 A b
## 3 2 A b
## 4 3 C a
## 5 3 C a
## 6 3 C a
## 7 2 A b
## 8 2 A b
缺失值处理
创建以下数据作为示例数据:
df02 <- data.frame(x = c(1, 2, NA, 3),
y = c("A", "C", "B", NA))
df02
## x y
## 1 1 A
## 2 2 C
## 3 NA B
## 4 3 <NA>
drop_na()
该函数会删掉选中变量为缺失值的行,若没有变量被选中则删掉所有包含缺失值的行。
drop_na(df02)
## x y
## 1 1 A
## 2 2 C
drop_na(df02, x)
## x y
## 1 1 A
## 2 2 C
## 3 3 <NA>
fill()
该函数会使用缺失值前一行(.direction = "down"
)或后一行(.direction = "up"
)的值代替缺失值。
## 默认使用前一行的值代替
fill(df02)
## x y
## 1 1 A
## 2 2 C
## 3 NA B
## 4 3 <NA>
## 设置.direction参数
fill(df02, x, .direction = "up")
## x y
## 1 1 A
## 2 2 C
## 3 3 B
## 4 3 <NA>
replace_na()
该函数使用特定的值来代替每个变量中的缺失值。
如使用数字4代替变量x
中的缺失值,使用"A"代替变量y
中的缺失值:
replace_na(df02, list(x = 4, y = "A"))
## x y
## 1 1 A
## 2 2 C
## 3 4 B
## 4 3 A
代替因子变量中的缺失值,必须是该变量中已出现的取值(即因子水平):
replace_na(df02, list(x = 4, y = "D"))
## Warning in `[<-.factor`(`*tmp*`, !is_complete(data[[var]]), value = "D"):
## invalid factor level, NA generated
## x y
## 1 1 A
## 2 2 C
## 3 4 B
## 4 3 <NA>
由于变量
y
为因子变量,而"D"在该变量中未曾出现,因此不能取代缺失值。
变量分列与合并
示例数据如下:
df03 <- billboard[,3]
df03
## # A tibble: 317 x 1
## date.entered
## <date>
## 1 2000-02-26
## 2 2000-09-02
## 3 2000-04-08
## 4 2000-10-21
## 5 2000-04-15
## 6 2000-08-19
## 7 2000-07-08
## 8 2000-01-29
## 9 2000-03-18
## 10 2000-08-26
## # ... with 307 more rows
separate()
该函数使用正则表达式将一个变量分为多个变量,类似Excel的数据分列功能。语法结构如下:
separate(data, col, into,
sep = "[^[:alnum:]]+",
remove = TRUE,
convert = FALSE,
extra = "warn",
fill = "warn", ...)
data:变量所在的数据框;
col:需要分列的变量;
into:分列后的变量名;
sep:正则表达式;
remove:是否将原变量从数据框中移除;默认为TRUE。
如通过符号-
将df03
中的日期变量分为年、月、日三个变量,并保留原日期变量:
separate(data = df03,
col = date.entered,
into = c("year", "month", "day"),
sep = "\\-",
remove = F) -> df04
df04
## # A tibble: 317 x 4
## date.entered year month day
## <date> <chr> <chr> <chr>
## 1 2000-02-26 2000 02 26
## 2 2000-09-02 2000 09 02
## 3 2000-04-08 2000 04 08
## 4 2000-10-21 2000 10 21
## 5 2000-04-15 2000 04 15
## 6 2000-08-19 2000 08 19
## 7 2000-07-08 2000 07 08
## 8 2000-01-29 2000 01 29
## 9 2000-03-18 2000 03 18
## 10 2000-08-26 2000 08 26
## # ... with 307 more rows
unite()
该函数与separate()
函数功能相反,用于将多个变量合并。语法结构如下:
unite(data, col, ...,
sep = "_",
remove = TRUE,
na.rm = FALSE)
col:合并后的变量名;
...:参与合并的变量;
sep:变量之间的连接符号。
unite(data = df04,
col = date,
year, month, day,
sep = "/")
## # A tibble: 317 x 2
## date.entered date
## <date> <chr>
## 1 2000-02-26 2000/02/26
## 2 2000-09-02 2000/09/02
## 3 2000-04-08 2000/04/08
## 4 2000-10-21 2000/10/21
## 5 2000-04-15 2000/04/15
## 6 2000-08-19 2000/08/19
## 7 2000-07-08 2000/07/08
## 8 2000-01-29 2000/01/29
## 9 2000-03-18 2000/03/18
## 10 2000-08-26 2000/08/26
## # ... with 307 more rows