美文网首页
7.数据整理

7.数据整理

作者: denghb001 | 来源:发表于2021-12-30 15:06 被阅读0次

有时候我们需要将数据展现的形式转换成另外一种样式的时候(比如将一列或多列数据纳入一列中),这个时候我们应该怎么做呢?倘若我们自己写代码完成的话,可能就会比较费时。这个时候我们可以使用 tidyverse 包中的提供的数据整理工具,这花费更少的时间将数据从一种表示转换为另一种表示,这样我们就会有更多的时间分析数据了。

1. 加载包

接下来我们将介绍tidyverse家族中的tidyr包,该包提供了一系列工具来整理凌乱的数据集。

library(tidyverse)

2. 整理数据

对同一数据集我们可以有不同的表示方式。下面的这个数据集(加载tidyverse后可直接查看)通过不同的方式显示了四个变量countryyearpopulationcases的值。

table1
#> # 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
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
#> # … with 6 more rows
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

# Spread across two tibbles
table4a  # cases
#> # A tibble: 3 x 3
#>   country     `1999` `2000`
#> * <chr>        <int>  <int>
#> 1 Afghanistan    745   2666
#> 2 Brazil       37737  80488
#> 3 China       212258 213766
table4b  # population
#> # A tibble: 3 x 3
#>   country         `1999`     `2000`
#> * <chr>            <int>      <int>
#> 1 Afghanistan   19987071   20595360
#> 2 Brazil       172006362  174504898
#> 3 China       1272915272 1280428583

这些数据集虽然都来自同一数据,但它们的使用场合不一定相同。一个整理过的数据集,在 tidyverse 中使用起来会方便很多。

数据整理有三个相互关联的规则:

  1. 每个变量都必须有自己的列。
  2. 每个观察都必须有自己的行。
  3. 每个值都必须有自己的单元格。

下图显示了该规则。

数据集整理三个规则:变量在列中,观察值在行中,值在单元格中。

为什么要进行数据整理呢?有两个主要优点:

  1. 选择一种相同的数据存储方式具有普遍优势。如果您拥有相同的数据结构,那么学习使用它的工具会更容易,因为它们具有潜在的一致性。
  2. 将变量放在列中有一个特定的优势,因为它可以让 R 的矢量化性质发挥作用。正如您在mutatesummary 函数中了解到的 ,大多数内置 R 函数都使用值向量。这使得转换整理过的数据就特别方便。

dplyr、ggplot2 和 tidyverse 中的包都可以整理数据,下面就来说明一下如何使用table1.

# Compute rate per 10,000
table1 %>% 
  mutate(rate = cases / population * 10000)
#> # A tibble: 6 x 5
#>   country      year  cases population  rate
#>   <chr>       <int>  <int>      <int> <dbl>
#> 1 Afghanistan  1999    745   19987071 0.373
#> 2 Afghanistan  2000   2666   20595360 1.29 
#> 3 Brazil       1999  37737  172006362 2.19 
#> 4 Brazil       2000  80488  174504898 4.61 
#> 5 China        1999 212258 1272915272 1.67 
#> 6 China        2000 213766 1280428583 1.67

# Compute cases per year
table1 %>% 
  count(year, wt = cases)
#> # A tibble: 2 x 2
#>    year      n
#>   <int>  <int>
#> 1  1999 250740
#> 2  2000 296920

# Visualise changes over time
library(ggplot2)
ggplot(table1, aes(year, cases)) + 
  geom_line(aes(group = country), colour = "grey50") + 
  geom_point(aes(colour = country))
image

3.数据转换

对于大多数实际的数据分析,需要进行进一步整理。首先要弄清楚变量和观察值是什么。接着你需要知道(1. 一个变量可能分布在多列中;2. 一项观察可能分散在多行中)

要解决这些问题,将需要用到 tidyr 中两个最重要的函数:pivot_longer()pivot_wider()

3.1 宽数据变长数据

有时候数据集的某些列名称不是变量名称,而是变量的。如table4a:列19992000代表year变量的值,19992000列中的值代表cases变量的值,每一行代表两个观察值,而不是一个。

table4a
#> # A tibble: 3 x 3
#>   country     `1999` `2000`
#> * <chr>        <int>  <int>
#> 1 Afghanistan    745   2666
#> 2 Brazil       37737  80488
#> 3 China       212258 213766

整理这样的数据集,我们需要转换列形成新的变量。为了描述该操作,我们需要三个参数:

  • 名称为值而非变量的列集。在这个例子中,那些是列19992000

  • 要将列名移动到的变量的名称。在这里year

  • 要将列值移动到的变量的名称。在这里cases

通过调用pivot_longer()来生成:

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

由于yearcases开始不存在,table4a所以我们将他们的名字放在引号中。

将“table4”转换成更长、更整洁的形式。

在最终结果中,要转换的列被删除,我们得到新的yearcases列。

pivot_longer()通过增加行数和减少列数来使数据集更长。我认为将数据集描述为“长格式”是没有意义的。长度是一个相对术语,您只能说(例如)数据集 A 比数据集 B 长。

我们可以用类似的方式pivot_longer()来整理table4b。唯一的区别是存储在单元格值中的变量:

table4b %>% 
  pivot_longer(c(`1999`, `2000`), names_to = "year", values_to = "population")
#> # A tibble: 6 x 3
#>   country     year  population
#>   <chr>       <chr>      <int>
#> 1 Afghanistan 1999    19987071
#> 2 Afghanistan 2000    20595360
#> 3 Brazil      1999   172006362
#> 4 Brazil      2000   174504898
#> 5 China       1999  1272915272
#> 6 China       2000  1280428583

要将table4atable4b的整理结果合并,我们需要使用dplyr::left_join()

tidy4a <- table4a %>% 
  pivot_longer(c(`1999`, `2000`), names_to = "year", values_to = "cases")
tidy4b <- table4b %>% 
  pivot_longer(c(`1999`, `2000`), names_to = "year", values_to = "population")
left_join(tidy4a, tidy4b)
#> Joining, by = c("country", "year")
#> # A tibble: 6 x 4
#>   country     year   cases population
#>   <chr>       <chr>  <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

3.2 长数据变宽数据

pivot_wider()pivot_longer()的反向操作。当观察值分散在多行中时,可以使用它。例如,假设table2:一个观察是一年中的一个国家,但每个观察都分布在两行中。

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
#> # … with 6 more rows

为了整理这些,我们首先以与pivot_longer()类似的方式分析表示。然而,pivot_wider()只需要两个参数:

  • 从中获取变量名的列。在这里是type

  • 要从中获取值的列。在这里count

table2 %>%
    pivot_wider(names_from = type, values_from = 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
image.png

正如你可能已经从他们的名字猜到了,pivot_wider()pivot_longer()是相互对立的。pivot_longer()使宽数据变窄变长;pivot_wider()使长数据变短变宽。

4. 拆分与合并

前面我们已经学会了如何整理table2table4。对于table3有一个不同的问题:我们有一列 ( rate) 包含两个变量 (casespopulation)。为了解决这个问题,我们需要这个separate()函数。

4.1 separate()

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

对于table3:该rate列同时包含casespopulation变量,我们需要将其拆分为两个变量。separate()获取要分隔的列的名称,以及要分隔后的列的名称,如图下面的代码所示。

table3 %>% 
  separate(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
分隔`table3`

我们可以通过sep参数来自定义设置要拆分的分隔符。

table3 %>% 
  separate(rate, into = c("cases", "population"), sep = "/")

仔细查看列类型:您会注意到casespopulation列是字符串。这是separate()中的默认方式:它保持列的类型不变。如果我们想转换类型,在separate()使用convert = TRUE转换为更好的类型:

table3 %>% 
  separate(rate, into = c("cases", "population"), convert = TRUE)
#> # 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

您还可以对sep传递整数向量。separate()将整数解释为要拆分的位置。正值从字符串最左侧的 1 开始;负值从字符串最右侧的 -1 开始。

table3 %>% 
  separate(year, into = c("century", "year"), sep = 2)
#> # 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

4.2 unite()

unite()separate()的倒数:它将多列合并为一列。与separate() 相比,使用它的频率要低得多,但是也是一个适用的工具。

合并`table5`

我们可以使用unite()来重新连接我们在上一个示例中创建的世纪年份列。该数据保存为tidyr::table5unite()需要一个数据框,要创建的新变量的名称,以及一组要组合的列。

table5 %>% 
  unite(new, century, year)
#> # A tibble: 6 x 3
#>   country     new   rate             
#>   <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

在这种情况下,我们还需要使用sep参数。默认将在来自不同列的值之间放置一个下划线 ( _)。这里我们不需要任何分隔符,所以我们使用""

table5 %>% 
  unite(new, century, year, sep = "")
#> # A tibble: 6 x 3
#>   country     new   rate             
#>   <chr>       <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

5. 缺失值

更改数据集的时候我们可能会遇到缺失值,缺失值一般以两种方式存在:

  • 明确地,即标记为NA
  • 隐含地,即根本不存在于数据中。

让我们通过一个非常简单的数据集来说明:

stocks <- tibble(
  year   = c(2015, 2015, 2015, 2015, 2016, 2016, 2016),
  qtr    = c(   1,    2,    3,    4,    2,    3,    4),
  return = c(1.88, 0.59, 0.35,   NA, 0.92, 0.17, 2.66)
)

此数据集中有两个缺失值:

  • 2015 年第四季度的回报明显缺失,因为其值所在的单元格为NA.
  • 2016 年第一季度的回报隐含缺失,因为它根本没有出现在数据集中。

这两种缺失值的差异:显式缺失值是存在缺失值;隐式缺失值是不存在。

改变数据集的表示方式可以使隐式值显式。例如,我们可以通过在列中放置年份来明确隐式缺失值:

stocks %>% 
  pivot_wider(names_from = year, values_from = return)
#> # 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

由于这些明确的缺失值可能不是在数据的其他表示中,你可以在pivot_longer()设置values_drop_na = TRUE转显性缺失值隐含的:

stocks %>% 
  pivot_wider(names_from = year, values_from = return) %>% 
  pivot_longer(
    cols = c(`2015`, `2016`), 
    names_to = "year", 
    values_to = "return", 
    values_drop_na = TRUE
  )
#> # A tibble: 6 x 3
#>     qtr year  return
#>   <dbl> <chr>  <dbl>
#> 1     1 2015    1.88
#> 2     2 2015    0.59
#> 3     2 2016    0.92
#> 4     3 2015    0.35
#> 5     3 2016    0.17
#> 6     4 2016    2.66

在整理的数据中明确缺失值的另一个重要工具是complete()

stocks %>% 
  complete(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
#> # … with 2 more rows

complete()接受一组列,并找到所有唯一的组合。然后确保原始数据集包含所有这些值,并在必要时填充显式NA

您应该了解另一个重要的工具来处理缺失值。有时,当数据源主要用于数据输入时,缺失值表示应结转先前的值:

treatment <- tribble(
  ~ person,           ~ treatment, ~response,
  "Derrick Whitmore", 1,           7,
  NA,                 2,           10,
  NA,                 3,           9,
  "Katherine Burke",  1,           4
)

您可以使用fill() 填充这些缺失值。它需要一组列,您希望将缺失值替换为最近的非缺失值(有时称为结转上次观察)。

treatment %>% 
  fill(person)
#> # A tibble: 4 x 3
#>   person           treatment response
#>   <chr>                <dbl>    <dbl>
#> 1 Derrick Whitmore         1        7
#> 2 Derrick Whitmore         2       10
#> 3 Derrick Whitmore         3        9
#> 4 Katherine Burke          1        4

6. 相关案例

接下来,我们将通过实际案例来解决数据整理的问题。tidyr::who数据集包含按年份、国家、年龄、性别和诊断方法细分的结核病 (TB) 病例。数据来自2014 年世界卫生组织全球结核病报告,可在此处下载。

该数据集中有大量流行病学信息,对于数据整理的需要有相当的挑战性:

who
#> # A tibble: 7,240 x 60
#>   country iso2  iso3   year new_sp_m014 new_sp_m1524 new_sp_m2534 new_sp_m3544
#>   <chr>   <chr> <chr> <int>       <int>        <int>        <int>        <int>
#> 1 Afghan… AF    AFG    1980          NA           NA           NA           NA
#> 2 Afghan… AF    AFG    1981          NA           NA           NA           NA
#> 3 Afghan… AF    AFG    1982          NA           NA           NA           NA
#> 4 Afghan… AF    AFG    1983          NA           NA           NA           NA
#> 5 Afghan… AF    AFG    1984          NA           NA           NA           NA
#> 6 Afghan… AF    AFG    1985          NA           NA           NA           NA
#> # … with 7,234 more rows, and 52 more variables: new_sp_m4554 <int>,
#> #   new_sp_m5564 <int>, new_sp_m65 <int>, new_sp_f014 <int>,
#> #   new_sp_f1524 <int>, new_sp_f2534 <int>, new_sp_f3544 <int>,
#> #   new_sp_f4554 <int>, new_sp_f5564 <int>, new_sp_f65 <int>,
#> #   new_sn_m014 <int>, new_sn_m1524 <int>, new_sn_m2534 <int>,
#> #   new_sn_m3544 <int>, new_sn_m4554 <int>, new_sn_m5564 <int>,
#> #   new_sn_m65 <int>, new_sn_f014 <int>, new_sn_f1524 <int>,
#> #   new_sn_f2534 <int>, new_sn_f3544 <int>, new_sn_f4554 <int>,
#> #   new_sn_f5564 <int>, new_sn_f65 <int>, new_ep_m014 <int>,
#> #   new_ep_m1524 <int>, new_ep_m2534 <int>, new_ep_m3544 <int>,
#> #   new_ep_m4554 <int>, new_ep_m5564 <int>, new_ep_m65 <int>,
#> #   new_ep_f014 <int>, new_ep_f1524 <int>, new_ep_f2534 <int>,
#> #   new_ep_f3544 <int>, new_ep_f4554 <int>, new_ep_f5564 <int>,
#> #   new_ep_f65 <int>, newrel_m014 <int>, newrel_m1524 <int>,
#> #   newrel_m2534 <int>, newrel_m3544 <int>, newrel_m4554 <int>,
#> #   newrel_m5564 <int>, newrel_m65 <int>, newrel_f014 <int>,
#> #   newrel_f1524 <int>, newrel_f2534 <int>, newrel_f3544 <int>,
#> #   newrel_f4554 <int>, newrel_f5564 <int>, newrel_f65 <int>

这是一个非常典型的数据集。它包含冗余列、奇数变量和许多缺失值。简而言之,who它很乱,我们需要多个步骤来整理它。与 dplyr 一样,tidyr 可以将多个函数串联到一个管道中。

开始我们可以将不是变量的列聚集在一起。让我们来看看我们有什么:

  • countryiso2iso3看起来像是三个冗余的变量(指定国家/地区)。

  • year 显然也是一个变量。

  • 我们还不知道所有其他列是什么,但鉴于变量名称中的结构(例如 new_sp_m014, new_ep_m014, new_ep_f014),这些很可能是值,而不是变量。

所以我们需要把从new_sp_m014newrel_f65的所有列聚集在一起。我们还不知道这些值代表什么,所以我们将给它们命名为"key"。我们知道单元格代表病例数,因此我们使用变量cases。当前表示中有很多缺失值,因此现在我们将使用values_drop_na去掉缺失值,我们可以直接研究存在的值。

who1 <- who %>% 
  pivot_longer(
    cols = new_sp_m014:newrel_f65, 
    names_to = "key", 
    values_to = "cases", 
    values_drop_na = TRUE
  )
who1
#> # A tibble: 76,046 x 6
#>   country     iso2  iso3   year key          cases
#>   <chr>       <chr> <chr> <int> <chr>        <int>
#> 1 Afghanistan AF    AFG    1997 new_sp_m014      0
#> 2 Afghanistan AF    AFG    1997 new_sp_m1524    10
#> 3 Afghanistan AF    AFG    1997 new_sp_m2534     6
#> 4 Afghanistan AF    AFG    1997 new_sp_m3544     3
#> 5 Afghanistan AF    AFG    1997 new_sp_m4554     5
#> 6 Afghanistan AF    AFG    1997 new_sp_m5564     2
#> # … with 76,040 more rows

我们可以通过计算新列中的key值的结构得到一些提示:

who1 %>% 
  count(key)
#> # A tibble: 56 x 2
#>   key              n
#>   <chr>        <int>
#> 1 new_ep_f014   1032
#> 2 new_ep_f1524  1021
#> 3 new_ep_f2534  1021
#> 4 new_ep_f3544  1021
#> 5 new_ep_f4554  1017
#> 6 new_ep_f5564  1017
#> # … with 50 more rows

您也许可以通过一些思考和一些实验自己解析出来:

  1. 每列的前三个字母表示该列是否包含新的或旧的结核病病例。在此数据集中,每一列都包含新案例。
  2. 接下来的两个字母描述了结核病的类型:
  • rel 代表复发病例
  • ep 代表肺外结核病例
  • sn 代表不能通过肺涂片(涂片阴性)诊断的肺结核病例
  • sp 代表可以通过肺涂片(涂片阳性)诊断的肺结核病例
  1. 第六个字母给出了结核病患者的性别。该数据集按男性 ( m) 和女性 ( f) 对案例进行分组。
  2. 剩下的数字给出了年龄组。该数据集将案例分为七个年龄组:
  • 014 = 0 – 14 岁
  • 1524 = 15 – 24 岁
  • 2534 = 25 – 34 岁
  • 3544 = 35 – 44 岁
  • 4554 = 45 – 54 岁
  • 5564 = 55 – 64 岁
  • 65 = 65 岁或以上

由于名称有点不一致,我们需要对列名的格式做一个小修正:将newrel改成new_rel(在这里很难发现这一点,但如果你不修复它,我们将在后续步骤中得到错误)。通过使用str_replace()在字符“newrel”替换为“new_rel”。这使所有变量名称保持一致。

who2 <- who1 %>% 
  mutate(key = stringr::str_replace(key, "newrel", "new_rel"))
who2
#> # A tibble: 76,046 x 6
#>   country     iso2  iso3   year key          cases
#>   <chr>       <chr> <chr> <int> <chr>        <int>
#> 1 Afghanistan AF    AFG    1997 new_sp_m014      0
#> 2 Afghanistan AF    AFG    1997 new_sp_m1524    10
#> 3 Afghanistan AF    AFG    1997 new_sp_m2534     6
#> 4 Afghanistan AF    AFG    1997 new_sp_m3544     3
#> 5 Afghanistan AF    AFG    1997 new_sp_m4554     5
#> 6 Afghanistan AF    AFG    1997 new_sp_m5564     2
#> # … with 76,040 more rows

我们可以通过separate()分割两次, 首先将在每个下划线处拆分代码。

who3 <- who2 %>% 
  separate(key, c("new", "type", "sexage"), sep = "_")
who3
#> # A tibble: 76,046 x 8
#>   country     iso2  iso3   year new   type  sexage cases
#>   <chr>       <chr> <chr> <int> <chr> <chr> <chr>  <int>
#> 1 Afghanistan AF    AFG    1997 new   sp    m014       0
#> 2 Afghanistan AF    AFG    1997 new   sp    m1524     10
#> 3 Afghanistan AF    AFG    1997 new   sp    m2534      6
#> 4 Afghanistan AF    AFG    1997 new   sp    m3544      3
#> 5 Afghanistan AF    AFG    1997 new   sp    m4554      5
#> 6 Afghanistan AF    AFG    1997 new   sp    m5564      2
#> # … with 76,040 more rows

由于new列在数据集中不变,我们将其删除,同时也删除掉多余的iso2iso3列。

who3 %>% 
  count(new)
#> # A tibble: 1 x 2
#>   new       n
#>   <chr> <int>
#> 1 new   76046
who4 <- who3 %>% 
  select(-new, -iso2, -iso3)

接着我们进行第二次拆分,将sexage分为sexage

who5 <- who4 %>% 
  separate(sexage, c("sex", "age"), sep = 1)
who5
#> # A tibble: 76,046 x 6
#>   country      year type  sex   age   cases
#>   <chr>       <int> <chr> <chr> <chr> <int>
#> 1 Afghanistan  1997 sp    m     014       0
#> 2 Afghanistan  1997 sp    m     1524     10
#> 3 Afghanistan  1997 sp    m     2534      6
#> 4 Afghanistan  1997 sp    m     3544      3
#> 5 Afghanistan  1997 sp    m     4554      5
#> 6 Afghanistan  1997 sp    m     5564      2
#> # … with 76,040 more rows

此时的who数据集我们处理后得到的最终数据样式。

上面的每步操作,我们可以通过管道连接符,建立一个复杂的管道:

who %>%
  pivot_longer(
    cols = new_sp_m014:newrel_f65, 
    names_to = "key", 
    values_to = "cases", 
    values_drop_na = TRUE
  ) %>% 
  mutate(
    key = stringr::str_replace(key, "newrel", "new_rel")
  ) %>%
  separate(key, c("new", "var", "sexage")) %>% 
  select(-new, -iso2, -iso3) %>% 
  separate(sexage, c("sex", "age"), sep = 1)

相关文章

  • 7.数据整理

    有时候我们需要将数据展现的形式转换成另外一种样式的时候(比如将一列或多列数据纳入一列中),这个时候我们应该怎么做呢...

  • 敏捷测试流程

    1.原型讨论2.测试点整理3.数据库测试4.代码测试5.功能测试6.集成测试7.系统测试

  • GenVisR基因组数据可视化实战(五)

    7. covBars 8. cnFreq 准备数据: 代码: 图: 9. ideoView 准备数据: 代码...

  • 7.数据规整

    数据转换 批量的修改列名、替换值以及重命名索引。 利用函数或映射进行数据转换 applymap是DataFrame...

  • 今日份计划

    1.洗碗 2.洗衣 2.1整理卫生间 3.整理餐厅 4.整理卧室 5.整理客厅 6.打扫地面 7.擦地板 5.花卉...

  • Spark经典案例之数据去重

    /** 业务场景:数据去重问题 Created by YJ on 2017/2/7. 统计数据,尽量用reduce...

  • Spark经典案例之数据去重

    /** 业务场景:数据去重问题 Created by YJ on 2017/2/7. 统计数据,尽量用reduce...

  • Spark经典案例之数据去重

    /** 业务场景:数据去重问题 Created by YJ on 2017/2/7. 统计数据,尽量用reduce...

  • Spark经典案例之数据去重

    /** 业务场景:数据去重问题 Created by YJ on 2017/2/7. 统计数据,尽量用reduce...

  • Spark经典案例之数据去重

    /** 业务场景:数据去重问题 Created by YJ on 2017/2/7. 统计数据,尽量用reduce...

网友评论

      本文标题:7.数据整理

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