美文网首页
Tidyverse ------Tidyr

Tidyverse ------Tidyr

作者: chensole | 来源:发表于2019-05-03 22:11 被阅读0次

趁着今天有时间,想着是不是该记录点东西了,没错是该记录一下了。今天的重头戏是tidyr package。
Tidy datasets are all alike, but every messy dataset is messy in its own way 。这是 Hadley Wickham(牛人)的总结。
数据预处理对于后续的分析很关键,处理过后的Tidy data 只要有三类特征:

  1. 每一列代表一个变量
  2. 每一行代表一个观测值
  3. 每一单元格代表一个value
    在Tidyverse(它是由RStudio选出多个资料科学应用套件的集合)中其他一些如dplyr、ggplot2等都是基于Tidy tada,下面这张图片很好的说明了tidy data的数据结构。这个内容也是我最近在学习的内容。


    2019-05-02 20-20-20 的屏幕截图.png

1. spreading and gathering

拿到一个数据首先要分辨出观测值和变量,然后就是解决两个很常见的问题:

  1. 一个变量分散在多列
  2. 一个观测分散在多行
    因此,就要进行长宽数据结构的转换,因此你需要用到tidyr package 中两个重要的函数: spread 和 gather

1.1 gather

让数据变成长窄型


2019-05-02 21-31-21 的屏幕截图.png
> table4a
# A tibble: 3 x 3
  country             `1999`  `2000`
* <chr>                   <int>      <int>
1 Afghanistan      745         2666
2 Brazil                37737       80488
3 China                212258    213766
对于上面的数据,可以看出1999和2000两列可以合并成一个新变量year,要完成这个转换:
        Usage :    gather(key= , value=  , ...)
          1. 为需要合并的多列定义新的变量名,key = "year"
          2. 为分布在单元格变量定义一个变量名,value = "cases"
          3. 设置需要合并成一个变量的列名,`1999`,`2000`,若需要合并成多列可直接指定列的索引值

tidy4a <- table4a  %>%  gahter (key = "year", value = "cases", `1999`,`2000`)
> tidy4a
# A tibble: 6 x 3
  country                    year   cases
  <chr>                        <chr>  <int>
1 Afghanistan         1999     745
2 Brazil                      1999   37737
3 China                     1999  212258
4 Afghanistan         2000    2666
5 Brazil                      2000   80488
6 China                      2000  213766

1.2 spread

让数据变成宽短型


2019-05-02 21-33-25 的屏幕截图.png
> table2
# A tibble: 12 x 4
   country                   year              type            count
   <chr>                      <int>             <chr>           <int>
 1 Afghanistan       1999              cases             745
 2 Afghanistan       1999         population   19987071
 3 Afghanistan       2000              cases            2666
 4 Afghanistan       2000         population   20595360
 5 Brazil                    1999             cases           37737
 6 Brazil                    1999         population  172006362
 7 Brazil                    2000            cases           80488
 8 Brazil                    2000        population   174504898
 9 China                   1999            cases            212258
10 China                  1999       population    1272915272
11 China                  2000            cases           213766
12 China                  2000       population    1280428583
对于上面的数据可以看出一个观测值是每个国家每一年的数据,然而每一个观测值确被分成两行排列,要完成这个转换:
      Usage: spread(key=  ,value = )
      1.  包含变量名的列,即key列,key = "type"
      2.  包含value的列,即value列,value = "count"
      对于这个函数的理解,将type列和count列每一行数据看成key-value pair ,从而利用spread对每一个key-value进行列的转换

table2 %>% spread(key = "type",value = "count")
# A tibble: 6 x 4
  country                   year         cases      population
  <chr>                       <int>         <int>          <int>
1 Afghanistan         1999          745         19987071
2 Afghanistan         2000         2666        20595360
3 Brazil                      1999        37737      172006362
4 Brazil                      2000        80488      174504898
5 China                     1999        212258    1272915272
6 China                     2000        213766    1280428583

2. Separating and uniting

对于一些数据,如果每一列的每一个单元格是由多个变量组成,那么我们需要将这一列分割成两列,这时候就要用到separate ; 又或者将多列合并成一列,就要用到unite

2.1 separate

> table3
# A tibble: 6 x 3
  country                    year             rate             
* <chr>                      <int>           <chr>            
1 Afghanistan          1999           745/19987071     
2 Afghanistan          2000           2666/20595360    
3 Brazil                       1999           37737/172006362  
4 Brazil                       2000           80488/174504898  
5 China                      1999            212258/1272915272
6 China                      2000            213766/1280428583
    Usage: separate (col = , into =  , sep =  )
    1. 定义需要分割的列名 col = "rate"
    2. 定义分割后的多个列名 into = c("cases", "population")
    3. 指定分隔符,默认以非字母、数字为分割符,也可用数字指定从字符串的那个字符分割

table3 %>% separate(col = rate,into = c("cases","population"))
# A tibble: 6 x 4
  country                             year    cases       population
  <chr>                                <int>    <chr>         <chr>     
1 Afghanistan                 1999      745          19987071  
2 Afghanistan                 2000     2666        20595360  
3 Brazil                             1999      37737     172006362 
4 Brazil                             2000      80488     174504898 
5 China                            1999      212258   1272915272
6 China                            2000      213766   1280428583
从返回的结果可以看出新生成的cases 和population两列数据类型为数值型,而结果是字符型,因此需要指定参数convert = TRUE
table3 %>% separate(col = rate,into = c("cases","population"),convert = TRUE)

table3 %>%  separate(year, into = c("century", "year"), sep = 2) # 表示从year列中第二个字符后进行分割
# A tibble: 6 x 4
  country                 century              year           rate             
  <chr>                      <chr>                 <chr>       <chr>            
1 Afghanistan          19                       99             745/19987071     
2 Afghanistan          20                       00             2666/20595360    
3 Brazil                       19                       99             37737/172006362  
4 Brazil                       20                       00             80488/174504898  
5 China                      19                       99              212258/1272915272
6 China                      20                       00              213766/1280428583

2.2 unite

对上面的数据century和year 两列进行合并
    Usage : unite(col = , ... , sep = ,)
    1. 定义合并后的列名
    2. 指定需要合并的多列(列名或索引)
    3. 指定合并后来自不同列数据的连接符,默认是"_" 

unite (col = "new" , "century", "year", sep = "")
# A tibble: 6 x 3
  country                    year             rate             
* <chr>                      <int>           <chr>            
1 Afghanistan          1999           745/19987071     
2 Afghanistan          2000           2666/20595360    
3 Brazil                       1999           37737/172006362  
4 Brazil                       2000           80488/174504898  
5 China                      1999            212258/1272915272
6 China                      2000            213766/1280428583

3. missing value

改变数据结构的同时,会出现一些缺失值,缺失值主要有以下两种方式: 1、原数据集中有NA 标记 ; 2、 有些观测值不存在数据集中

> stocks
# A tibble: 7 x 3
   year      qtr     return
  <dbl>  <dbl>  <dbl>
1  2015     1       1.88
2  2015     2       0.59
3  2015     3       0.35
4  2015     4       NA   
5  2016     2      0.92
6  2016     3      0.17
7  2016     4      2.66
观测数据可以看出: 有一个明确的缺失值NA, 还有一个隐藏的观测值缺失
为了让隐藏的缺失值变成NA,可以spread 将year列展开

stocks %>% spread(key = year,value = return)
>stocks
# A tibble: 4 x 3
    qtr     `2015`  `2016`
  <dbl>   <dbl>     <dbl>
1     1        1.88         NA   
2     2        0.59        0.92
3     3        0.35        0.17
4     4         NA          2.66
一般原本存在的NA可能不是很重要,因此你可以利用gather将NA变成隐藏的缺失。

stocks %>% spread(key = year,value = return)  %>% gather (key = "year" , value = "return" ,`2015`,`2016`, na.rm = TRUE)
# A tibble: 6 x 3
    qtr        year        count
  <dbl>   <chr>      <dbl>
1     1       2015        1.88
2     2       2015        0.59
3     3       2015        0.35
4     2       2016        0.92
5     3       2016        0.17
6     4       2016        2.66

另一个让隐藏的缺失值变成NA的函数: complete()
stocks %>%  complete(year, qtr) #列出year和qtr所有的观测组合
# A tibble: 8 x 3
   year          qtr   return
  <dbl>     <dbl>  <dbl>
1  2015         1       1.88
2  2015         2       0.59
3  2015         3       0.35
4  2015         4        NA   
5  2016         1        NA   
6  2016         2       0.92
7  2016         3       0.17
8  2016         4       2.66

还有一种情况就是对于数据录入员来说,有时候缺失值表示与之前值相同故而省略
> treament
# A tibble: 4 x 3
  person                     treament     response
  <chr>                           <dbl>          <dbl>
1 Derrick Whitmore        1                  7
2 NA                                       2                10
3 NA                                       3                  7
4 Katherine Burke           1                  4

treatment %>% fill(person)

# A tibble: 4 x 3
  person                              treament response
  <chr>                                    <dbl>    <dbl>
1 Derrick Whitmore              1             7
2 Derrick Whitmore              2            10
3 Derrick Whitmore              3             7
4 Katherine Burke                 1             4

有了Tidy data,我们就可以开展后续数据整理和分析,这就要介绍到Tidyverse家族另一个重要的dplyr package,可以实现类似SQL的功能,虽然一些R基础包中函数也可以完成目标,但是当你熟悉了dplyr的操作,你会感到很High!!!

附上原文链接: https://r4ds.had.co.nz/

相关文章

  • Tidyverse ------Tidyr

    趁着今天有时间,想着是不是该记录点东西了,没错是该记录一下了。今天的重头戏是tidyr package。Tidy ...

  • 载入R包报错:Error: package or namespa

    library(tidyverse) # ggplot2 stringer dplyr tidyr readr p...

  • tidyverse包-tidyr

    ggplot2画箱线图 每个箱线图叠加,一步步操作,这样太麻烦了,换个方法,用tidyverse包里的gather...

  • 学习小组Day6笔记——TheCatcher

    安装和加载tidyr包 因为之前安装过tidyverse包,已经将tidyr包含在内,所以就直接library啦,...

  • 数据挖掘0309

    所有资料来源于生信技能树 Tidyverse包 1. 简介 1.1 Tidyr (1)Tidyr的扁与长 gath...

  • tidyverse包进行R语言数据清洗

    这次用的包是要是tidyverse包,安装不上tidyverse包,可以安装tidyr包。 熊老师其实还是建议家直...

  • R语言基础学习7

    人见人爱 tidyverse tidyrdplyrstringrggplot2 安装好包 1 数据清理 tidyr...

  • 11-24

    一、tidyverse的简介 tidyr dplyr stringr ggplot2 二、管道符号%>% merg...

  • 替代apply家族的map家族

    高效数据处理组合 tidyverse包中就是这种组合:tidyr + dplyr + purrr,如下所示: 学习...

  • 六、R语言进阶

    1.tidyverse (1)tidyr 核心函数 1)数据清理 2)分割和合并 3)处理NA 2.dplyr (...

网友评论

      本文标题:Tidyverse ------Tidyr

      本文链接:https://www.haomeiwen.com/subject/bgqonqtx.html