tidyr | 变量取值组合、缺失值处理、变量分列与合并

关于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
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值