3.5 字符处理
有时候我们要将多个变量合并到一列中,或者分离为单独的列。tidyr 中提供了一组函数实现该部分功能。
3.5.1 新列提取
extract()
函数将字符列提取为多列。所以该函数能实现的功能,大部分基于对正则表达式的使用。和 Excel 中的 Ctrl + E
用法类似。
3.5.1.1 参数
extract(
data,
col,
into,regex = "([[:alnum:]]+)",
remove = TRUE,
convert = FALSE,
... )
data : 一个数据框
col : 被提取的列
into : 新列名
regex : 提取所需值的正则表达式
remove : 默认为 FALSE ,如果为TRUE,将从输出的数据框中删除输入列
3.5.1.2 案例
<- data.frame(x = c(NA, "a-b", "a-d", "b-c", "d-e"))
df %>% extract(x, "A")
df #> A
#> 1 <NA>
#> 2 a
#> 3 a
#> 4 b
#> 5 d
%>% extract(x, c("A", "B"), "([[:alnum:]]+)-([[:alnum:]]+)")
df #> A B
#> 1 <NA> <NA>
#> 2 a b
#> 3 a d
#> 4 b c
#> 5 d e
[:alnum:] 匹配任何字母,[:alpha:] 匹配任何字母和数字
<- data.frame(x = c("1992-04", "1992-05", "1992-06", "1992-07", "1992-08", "1992-09", "1992-10", "1992-11", "1992-12"))
df
%>%
df extract(col = x,into = c('年','月'),regex = "([1-9]{4})-([0-9]{2})")
#> 年 月
#> 1 1992 04
#> 2 1992 05
#> 3 1992 06
#> 4 1992 07
#> 5 1992 08
#> 6 1992 09
#> 7 1992 10
#> 8 1992 11
#> 9 1992 12
# 字符转化为数字
%>%
df extract(col = x,into = c('年','月'),regex = "([1-9]{4})-([0-9]{2})",convert = TRUE)
#> 年 月
#> 1 1992 4
#> 2 1992 5
#> 3 1992 6
#> 4 1992 7
#> 5 1992 8
#> 6 1992 9
#> 7 1992 10
#> 8 1992 11
#> 9 1992 12
正则表达式([1-9]{4})-([0-9]{2})
代表:字符分为两部分,中间用“-”连接,前半部分匹配1-9中的任意4位数,后半部分匹配0-9中任意两位数。
3.5.2 拆分
有时我们需要将一列拆分为多列,使用separate()
函数。
3.5.2.1 参数
separate(
data,
col,
into,sep = "[^[:alnum:]]+",
remove = TRUE,
convert = FALSE,
extra = "warn",
fill = "warn",
... )
参数 sep 指定列之间的分隔符,sep 参数为字符时被解释为正则表达式,默认值是匹配任何非字母数字的正则表达式
<- data.frame(x = c(NA, "a.b", "a.d", "b.c"))
df %>% separate(col = x, into = c("A", "B"))
df #> A B
#> 1 <NA> <NA>
#> 2 a b
#> 3 a d
#> 4 b c
3.5.2.2 案例
#sep 参数为字符时被解释为正则表达式,默认值是匹配任何非字母数字的正则表达式
%>% separate(col = x, into = c("A", "B"))
df #> A B
#> 1 <NA> <NA>
#> 2 a b
#> 3 a d
#> 4 b c
# 同上
%>% separate(x, c("A", "B"),sep = '\\.')
df #> A B
#> 1 <NA> <NA>
#> 2 a b
#> 3 a d
#> 4 b c
# 只要第二个变量
%>% separate(x, c(NA, "B"))
df #> B
#> 1 <NA>
#> 2 b
#> 3 d
#> 4 c
#sep 参数为数字时被解释为要拆分的字符位置
%>% separate(x, c("A", "B"),sep = 2)
df #> A B
#> 1 <NA> <NA>
#> 2 a. b
#> 3 a. d
#> 4 b. c
拆分时,多列或少列时用NA
补齐:
<- data.frame(x = c("x", "x y", "x y z", NA))
df %>% separate(x, c("a", "b"))
df #> Warning: Expected 2 pieces. Additional pieces discarded in 1 rows [3].
#> Warning: Expected 2 pieces. Missing pieces filled with `NA` in 1 rows [1].
#> a b
#> 1 x <NA>
#> 2 x y
#> 3 x y
#> 4 <NA> <NA>
多余的部分舍弃,缺失填充在左边还是右边:
%>% separate(x, c("a", "b"), extra = "drop", fill = "right")
df #> a b
#> 1 x <NA>
#> 2 x y
#> 3 x y
#> 4 <NA> <NA>
多余部分合并,缺失填充在左边
%>% separate(x, c("a", "b"), extra = "merge", fill = "left")
df #> a b
#> 1 <NA> x
#> 2 x y
#> 3 x y z
#> 4 <NA> <NA>
或者全部保留
%>% separate(x, c("a", "b", "c"))
df #> Warning: Expected 3 pieces. Missing pieces filled with `NA` in 2 rows [1, 2].
#> a b c
#> 1 x <NA> <NA>
#> 2 x y <NA>
#> 3 x y z
#> 4 <NA> <NA> <NA>
指定分隔符
%>% separate(x, c("key", "value"), sep = ": ", extra = "merge")
df #> Warning: Expected 2 pieces. Missing pieces filled with `NA` in 3 rows [1, 2, 3].
#> key value
#> 1 x <NA>
#> 2 x y <NA>
#> 3 x y z <NA>
#> 4 <NA> <NA>
使用正则表达式
# Use regular expressions to separate on multiple characters:
<- data.frame(x = c(NA, "a?b", "a.d", "b:c"))
df %>% separate(x, c("A","B"), sep = "([.?:])")
df #> A B
#> 1 <NA> <NA>
#> 2 a b
#> 3 a d
#> 4 b c
3.5.3 列拆分行
separate_rows(data, ..., sep = "[^[:alnum:].]+", convert = FALSE)
<- tibble(
df x = 1:3,
y = c("a", "d,e,f", "g,h"),
z = c("1", "2,3,4", "5,6")
)separate_rows(df, y, z, convert = TRUE)
#> # A tibble: 6 x 3
#> x y z
#> <int> <chr> <int>
#> 1 1 a 1
#> 2 2 d 2
#> 3 2 e 3
#> 4 2 f 4
#> 5 3 g 5
#> 6 3 h 6
3.5.4 合并多列
unite()
方便将多列合并一列。
用法
unite(data, col, ..., sep = "_", remove = TRUE, na.rm = FALSE)
<- data.frame(x = letters[1:6],y = LETTERS[1:6])
df %>% unite("z",x:y,sep="_")
df #> z
#> 1 a_A
#> 2 b_B
#> 3 c_C
#> 4 d_D
#> 5 e_E
#> 6 f_F
%>% unite("z",x:y,sep="_",remove = FALSE)
df #> z x y
#> 1 a_A a A
#> 2 b_B b B
#> 3 c_C c C
#> 4 d_D d D
#> 5 e_E e E
#> 6 f_F f F
%>%
df unite("z",x:y,sep="_") %>%
separate(col = z,into = c('x','y'),sep = "_")
#> x y
#> 1 a A
#> 2 b B
#> 3 c C
#> 4 d D
#> 5 e E
#> 6 f F