美文网首页
6.数据导入

6.数据导入

作者: denghb001 | 来源:发表于2021-12-24 11:03 被阅读0次

    数据导入

    1.简介

    有的时候我们直接使用R包中提供的数据来进行分析,是一个很好的方法,但是我们想使用自己的数据时,就需要将数据读入到R中。我们接下来将了解如何使用readr包在 R 中加载文件,readr包是tidyverse包的核心部分。

    1.1先决条件

    我们需要加载tidyverse包

    library(tidyverse)
    

    2.入门

    readr 的大部分函数都是将文件转换为数据框:

    • read_csv()读取逗号分隔的文件,read_csv2()读取分号分隔的文件(在,用作小数位的国家中常见), read_tsv()读取制表符分隔的文件,read_delim()读取带有任何分隔符的文件。

    • read_fwf()读取固定宽度的文件。您可以通过指定其宽度fwf_widths()fwf_positions()指定字段位置来读取文件。 read_table()读取固定宽度文件,其中列由空格分隔。

    • read_log()读取 Apache 格式的日志文件

    这些函数的用法都相似:我们只要掌握了其中一个的使用方法,其它的函数就能运用自如。接下来我们将主要了解read_csv()。(csv 文件是最常见的数据存储形式之一)

    read_csv()的第一个参数是最重要的:它是读取的文件的路径。

    heights <- read_csv("data/heights.csv")
    #> 
    #> ── Column specification ────────────────────────────────────────────────────────
    #> cols(
    #>   earn = col_double(),
    #>   height = col_double(),
    #>   sex = col_character(),
    #>   ed = col_double(),
    #>   age = col_double(),
    #>   race = col_character()
    #> )
    

    当您运行read_csv()时,它会打印出一个列规范,其中给出了每列的名称和类型。这是 readr 的一个重要组成部分。

    您还可以提供内联 csv 文件进行读取:

    read_csv("a,b,c
    1,2,3
    4,5,6")
    #> # A tibble: 2 x 3
    #>       a     b     c
    #>   <dbl> <dbl> <dbl>
    #> 1     1     2     3
    #> 2     4     5     6
    

    在以上两种情况下,read_csv()列名都使用数据的第一行,这是默认的约定。有时候文件的开头可能不是我们想要的数据,我们可以通过skip = n或者comment = "#"来忽略。

    ```
    read_csv("The first line of metadata
      The second line of metadata
      x,y,z
      1,2,3", skip = 2)
    #> # A tibble: 1 x 3
    #>       x     y     z
    #>   <dbl> <dbl> <dbl>
    #> 1     1     2     3
    
    read_csv("# A comment I want to skip
      x,y,z
      1,2,3", comment = "#")
    #> # A tibble: 1 x 3
    #>       x     y     z
    #>   <dbl> <dbl> <dbl>
    #> 1     1     2     3
    ```
    

    有时数据可能没有列名。您可以使用col_names = FALSE来告诉read_csv()不要将第一行视为标题,而是通过X1Xn顺序默认标记:

    ```
    read_csv("1,2,3\n4,5,6", col_names = FALSE)
    #> # A tibble: 2 x 3
    #>      X1    X2    X3
    #>   <dbl> <dbl> <dbl>
    #> 1     1     2     3
    #> 2     4     5     6
    ```
    

    你也可以自定义命名列名称 col_names

    ```
    read_csv("1,2,3\n4,5,6", col_names = c("x", "y", "z"))
    #> # A tibble: 2 x 3
    #>       x     y     z
    #>   <dbl> <dbl> <dbl>
    #> 1     1     2     3
    #> 2     4     5     6
    ```
    

    另一个通常需要调整的选项是na:这指定了用于表示文件中缺失值的一个(或多个)值:

    read_csv("a,b,c\n1,2,.", na = ".")
    #> # A tibble: 1 x 3
    #>       a     b c    
    #>   <dbl> <dbl> <lgl>
    #> 1     1     2 NA
    

    2.1 与 R中的base包比较

    以前我们经常使用read.csv()来读取文件,那为什么我们现在要选择readr包中的read_csv呢?下面就列出了使用readr的优点:

    • readr包中的函数通常比base中的快得多(~10 倍)。

    • readr中可以生成小标题,而且不会将字符向量转换为因子、使用行名称或修改列名称。

    • 可重复性更高。

    3. 解析向量

    在我们深入了解readr如何从磁盘读取文件之前,我们需要先了解解析函数parse_*()。这些函数接受一个字符向量并返回一个更特殊的向量,如逻辑、整数或日期:

    str(parse_logical(c("TRUE", "FALSE", "NA")))
    #>  logi [1:3] TRUE FALSE NA
    str(parse_integer(c("1", "2", "3")))
    #>  int [1:3] 1 2 3
    str(parse_date(c("2010-01-01", "1979-10-14")))
    #>  Date[1:2], format: "2010-01-01" "1979-10-14"
    

    与 tidyverse 中的所有函数一样,这些parse_*()函数是统一的:第一个参数是要解析的字符向量,该na参数指定应将哪些字符串视为缺失:

    parse_integer(c("1", "231", ".", "456"), na = ".")
    #> [1]   1 231  NA 456
    

    如果解析失败,您将收到警告:

    x <- parse_integer(c("123", "345", "abc", "123.45"))
    #> Warning: 2 parsing failures.
    #> row col               expected actual
    #>   3  -- an integer             abc   
    #>   4  -- no trailing characters 123.45
    

    并且输出中结果中不显示未解析出的值,通过NA代替:

    x
    #> [1] 123 345  NA  NA
    #> attr(,"problems")
    #> # A tibble: 2 x 4
    #>     row   col expected               actual
    #>   <int> <int> <chr>                  <chr> 
    #> 1     3    NA an integer             abc   
    #> 2     4    NA no trailing characters 123.45
    

    如果有很多解析失败,可以使用problems()来获取完整集。这将返回一个小标题,然后您可以使用 dplyr 对其进行操作。

    problems(x)
    #> # A tibble: 2 x 4
    #>     row   col expected               actual
    #>   <int> <int> <chr>                  <chr> 
    #> 1     3    NA an integer             abc   
    #> 2     4    NA no trailing characters 123.45
    

    使用解析器主要是确定哪些内容是我们可用的,以及我们你该如何处理不同类型的输入。下面列出了八个特别重要的解析器:

    1. parse_logical()parse_integer()分别解析逻辑值和整数。

    2. parse_double()是一个严格的数值解析器,parse_number() 是一个灵活的数值解析器。因为世界不同地区书写数字的方式不同,就可能比较复杂。

    3. parse_character()看起来很简单,但有一个复杂因素使它变得非常重要:字符编码。

    4. parse_factor() 创建因子,R 用于表示具有固定值和已知值的分类变量的数据结构。

    5. parse_datetime(), parse_date(), 和parse_time()允许您解析各种日期和时间规范。这些是最复杂的,因为有很多不同的日期书写方式。

    下面我们来详细了解这些解析器吧!

    3.1 数字

    解析一个数字看似很简单,当时需要注意以下三个问题:

    1. 世界不同地区的人们写数字的方式不同。例如,一些国家在实数的整数部分和小数部分之间使用.,而其他国家则使用,

    2. 数字被其他字符包围,例如“$1000”或“10%”。

    3. 为了便于阅读,数字包含“分组”字符,例如“1,000,000”,并且这些分组字符在世界范围内各不相同。

    为了解决第一个问题,readr 有一个“locale”的概念,该对象指定了不同地方的解析参数。解析数字时,最重要的选项是用于小数点的字符。可以通过创建新的语言环境并设置decimal_mark参数来覆盖的默认值.

    parse_double("1.23")
    #> [1] 1.23
    parse_double("1,23", locale = locale(decimal_mark = ","))
    #> [1] 1.23
    

    readr 的默认语言环境以美国为中心(即基本 R 的文档是用美式英语编写的)。另一种方法是尝试猜测操作系统的默认值。这很难做好,这样会使您的代码变得脆弱:即使它在您的计算机上运行,当您通过电子邮件将其发送给另一个国家的同事时,它也可能会失败。

    parse_number()用来解决第二个问题:它忽略数字前后的非数字字符。这对于货币和百分比特别有用,但也适用于提取嵌入文本中的数字。

    parse_number("$100")
    #> [1] 100
    parse_number("20%")
    #> [1] 20
    parse_number("It cost $123.45")
    #> [1] 123.45
    

    最后一个问题是通过parse_number()local语言环境的组合来解决的,因为parse_number()将忽略“grouping_mark”:

    # Used in America
    parse_number("$123,456,789")
    #> [1] 123456789
    
    # Used in many parts of Europe
    parse_number("123.456.789", locale = locale(grouping_mark = "."))
    #> [1] 123456789
    
    # Used in Switzerland
    parse_number("123'456'789", locale = locale(grouping_mark = "'"))
    #> [1] 123456789
    

    3.2 字符串

    parse_character()看起来虽然很简单——只返回它的输入。然而一个字符串可以用不同的方法表示(如八进制、十六进制)。在 R 中,我们可以使用charToRaw()取字符串的底层表示:

    charToRaw("Hadley")
    #> [1] 48 61 64 6c 65 79
    

    每个十六进制数代表一个字节的信息:48代表 H,61代表 a,等等。从十六进制数到字符的映射称为编码,在这种情况的编码称为 ASCII。ASCII 在表示英文字符方面做得很好,因为它是美国信息交换标准代码(American Standard Code for Information Interchange)。

    对于英语以外的语言,就变得更加复杂。在计算机的早期,有许多非英语字符编码标准,如果要正确解释字符串,您需要知道相应的值和编码。例如,两种常见的编码是 Latin1(又名 ISO-8859-1,用于西欧语言)和 Latin2(又名 ISO-8859-2,用于东欧语言)。在Latin1 中,字节b1是“±”,但在Latin2 中,它是“ą”,为了解决这一问题,国际上采用通用编码格式:UTF-8。UTF-8 几乎可以编码当今人类使用的每个字符,以及许多额外的符号(例如表情符号!)。

    readr 在任何地方都使用 UTF-8:它假定您的数据在读取时是 UTF-8 编码的,并且在写入时始终使用UTF-8。这是非常好的默认值,但对于不理解 UTF-8 的旧系统生成的数据时将会出错。如果您遇到这种情况,打印它们时您的字符串会看起来很奇怪。有时可能只有一两个字符会被弄乱或者完全乱码。例如:

    x1 <- "El Ni\xf1o was particularly bad this year"
    x2 <- "\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd"
    
    x1
    #> [1] "El Ni\xf1o was particularly bad this year"
    x2
    #> [1] "\x82\xb1\x82\xf1\x82\u0242\xbf\x82\xcd"
    

    要解决此问题,您需要在parse_character()中指定编码:

    parse_character(x1, locale = locale(encoding = "Latin1"))
    #> [1] "El Niño was particularly bad this year"
    parse_character(x2, locale = locale(encoding = "Shift-JIS"))
    #> [1] "こんにちは"
    

    一般我们得到的字符串,并不知道它们是怎么编码的,这个时候该怎么办呢?可以使用 readr 提供guess_encoding()解决。

    guess_encoding(charToRaw(x1))
    #> # A tibble: 2 x 2
    #>   encoding   confidence
    #>   <chr>           <dbl>
    #> 1 ISO-8859-1       0.46
    #> 2 ISO-8859-9       0.23
    guess_encoding(charToRaw(x2))
    #> # A tibble: 1 x 2
    #>   encoding confidence
    #>   <chr>         <dbl>
    #> 1 KOI8-R         0.42
    

    guess_encoding()的第一个参数可以是文件的路径,也可以是原始向量(如果字符串已经在 R 中,则在这种情况下很有用)。

    编码是一个丰富而复杂的话题,如果您想了解更多信息,我建议您阅读http://kunststube.net/encoding/的详细说明。

    3.3 因子

    R 使用因子来表示具有一组已知可能值的分类变量。parse_factor()给出一个已知向量levels,在出现意外值时生成警告:

    fruit <- c("apple", "banana")
    parse_factor(c("apple", "banana", "bananana"), levels = fruit)
    #> Warning: 1 parsing failure.
    #> row col           expected   actual
    #>   3  -- value in level set bananana
    #> [1] apple  banana <NA>  
    #> attr(,"problems")
    #> # A tibble: 1 x 4
    #>     row   col expected           actual  
    #>   <int> <int> <chr>              <chr>   
    #> 1     3    NA value in level set bananana
    #> Levels: apple banana
    

    3.4 日期、日期时间和时间

    您是否可以在没有任何附加参数的情况下,调用需要的日期(从1970-01-01 以来的天数)、日期时间(自 1970-01-01 午夜以来的秒数)或时间(从自午夜以来的秒数)。

    • parse_datetime()参照的是 ISO8601 日期时间。ISO8601 是一项国际标准,其中日期的组成部分从大到小排列:年、月、日、小时、分钟、秒。

      parse_datetime("2010-10-01T2010")
      #> [1] "2010-10-01 20:10:00 UTC"
      # If time is omitted, it will be set to midnight
      parse_datetime("20101010")
      #> [1] "2010-10-10 UTC"
      

      这是最重要的日期/时间标准,如果您经常使用日期和时间,可以参考 https://en.wikipedia.org/wiki/ISO_8601了解更多。

    • parse_date() 一般格式是2021-01-012021/01/01

      parse_date("2010-10-01")
      #> [1] "2010-10-01"
      
    • parse_time() 由期望小时、:分钟、可选:秒,以及可选的 am/pm 说明:

      library(hms)
      parse_time("01:10 am")
      #> 01:10:00
      parse_time("20:10:01")
      #> 20:10:01
      

      Base R 没有很好的内置时间数据类,可以使用 hms 包中提供的类。

    如果这些默认值不适用于您的数据,您可以提供您自己的 date-time 格式,由以下部分组成:

    Year
    %Y (4 digits).
    %y (2 digits); 00-69 -> 2000-2069, 70-99 -> 1970-1999.
    Month
    %m (2 digits).
    %b (abbreviated name, like “Jan”).
    %B (full name, “January”).
    Day
    %d (2 digits).
    %e (optional leading space).
    Time
    %H 0-23 hour.
    %I 0-12, must be used with %p.
    %p AM/PM indicator.
    %M minutes.
    %S integer seconds.
    %OS real seconds.
    %Z 时区(作为名称,例如America/Chicago)。
    %z(与UTC的偏移量,例如+0800)。
    Non-digits
    %. skips one non-digit character.
    %* skips any number of non-digits.

    找出正确格式的最好方法是在字符向量中创建示例格式,并使用其中一个解析函数进行测试。例如:

    parse_date("01/02/15", "%m/%d/%y")
    #> [1] "2015-01-02"
    parse_date("01/02/15", "%d/%m/%y")
    #> [1] "2015-02-01"
    parse_date("01/02/15", "%y/%m/%d")
    #> [1] "2001-02-15"
    

    如果您使用%b%B使用非英语月份名称,则需要将lang参数设置为locale(). 请参阅date_names_langs()中的内置语言列表,或者如果您的语言尚未包含在内,请使用date_names()来创建您自己的语言。

    parse_date("1 janvier 2015", "%d %B %Y", locale = locale("fr"))
    #> [1] "2015-01-01"
    

    4 解析文件

    现在已经学会了如何解析单个向量,那么 readr 是如何解析文件的呢?下面我们将学习两个新内容:

    1. readr 如何自动猜测每一列的类型。
    2. 如何覆盖默认值。

    4.1 方法

    readr 使用试探法来确定每列的类型:它读取前 1000 行并使用一些(适度保守的)试探法来确定每列的类型。您可以使用字符向量来模拟这个过程guess_parser(),它会返回最佳的猜测,parse_guess()使用该猜测来解析列:

    guess_parser("2010-10-01")
    #> [1] "date"
    guess_parser("15:01")
    #> [1] "time"
    guess_parser(c("TRUE", "FALSE"))
    #> [1] "logical"
    guess_parser(c("1", "5", "9"))
    #> [1] "double"
    guess_parser(c("12,352,561"))
    #> [1] "number"
    
    str(parse_guess("2010-10-10"))
    #>  Date[1:1], format: "2010-10-10"
    

    通过尝试以下每种类型,在找到匹配项时停止:

    • 逻辑:仅包含“F”、“T”、“FALSE”或“TRUE”。
    • 整数:仅包含数字字符(和-)。
    • double: 只包含有效的 doubles(包括像 的数字4.5e-5)。
    • 数字:包含带有分组标记的有效双打。
    • 时间:匹配默认值time_format
    • 日期:匹配默认值date_format
    • 日期时间:任何 ISO8601 日期。

    如果上面这些规则都不适用,则该列将保留为字符串向量。

    4.2 问题

    这些默认值并不总是适用于较大的文件。有两个基本问题:

    1. 前1000行可能是一个特例,猜测的类型并不适用与所有列。例如,前1000行是整数后面的行全是双精度。

    2. 该列可能包含许多缺失值。如果前 1000 行仅包含NA,则 readr 会猜测它是一个逻辑向量,而您可能希望将其解析为更具体的内容。

    readr 有一个具有挑战性的 CSV文件,它说明了这两个问题:

    challenge <- read_csv(readr_example("challenge.csv"))
    #> 
    #> ── Column specification ────────────────────────────────────────────────────────
    #> cols(
    #>   x = col_double(),
    #>   y = col_logical()
    #> )
    #> Warning: 1000 parsing failures.
    #>  row col           expected     actual                                                           file
    #> 1001   y 1/0/T/F/TRUE/FALSE 2015-01-16 '/Users/runner/work/_temp/Library/readr/extdata/challenge.csv'
    #> 1002   y 1/0/T/F/TRUE/FALSE 2018-05-18 '/Users/runner/work/_temp/Library/readr/extdata/challenge.csv'
    #> 1003   y 1/0/T/F/TRUE/FALSE 2015-09-05 '/Users/runner/work/_temp/Library/readr/extdata/challenge.csv'
    #> 1004   y 1/0/T/F/TRUE/FALSE 2012-11-28 '/Users/runner/work/_temp/Library/readr/extdata/challenge.csv'
    #> 1005   y 1/0/T/F/TRUE/FALSE 2020-01-13 '/Users/runner/work/_temp/Library/readr/extdata/challenge.csv'
    #> .... ... .................. .......... ..............................................................
    #> See problems(...) for more details.
    

    (注意使用readr_example()which() 可以找到包中包含的示例文件的路径)

    有两个打印输出:通过查看前 1000 行生成的列规范,以及前五个解析失败。通过使用problems()来详细了解:

    problems(challenge)
    #> # A tibble: 1,000 x 5
    #>     row col   expected        actual   file                                     
    #>   <int> <chr> <chr>           <chr>    <chr>                                    
    #> 1  1001 y     1/0/T/F/TRUE/F… 2015-01… '/Users/runner/work/_temp/Library/readr/…
    #> 2  1002 y     1/0/T/F/TRUE/F… 2018-05… '/Users/runner/work/_temp/Library/readr/…
    #> 3  1003 y     1/0/T/F/TRUE/F… 2015-09… '/Users/runner/work/_temp/Library/readr/…
    #> 4  1004 y     1/0/T/F/TRUE/F… 2012-11… '/Users/runner/work/_temp/Library/readr/…
    #> 5  1005 y     1/0/T/F/TRUE/F… 2020-01… '/Users/runner/work/_temp/Library/readr/…
    #> 6  1006 y     1/0/T/F/TRUE/F… 2016-04… '/Users/runner/work/_temp/Library/readr/…
    #> # … with 994 more rows
    

    一个好的方法是逐列运行,直到没有问题为止。在这里我们可以看到解析y列有很多问题。如果我们查看最后几行,您会发现它们是存储在字符向量中的日期:

    tail(challenge)
    #> # A tibble: 6 x 2
    #>       x y    
    #>   <dbl> <lgl>
    #> 1 0.805 NA   
    #> 2 0.164 NA   
    #> 3 0.472 NA   
    #> 4 0.718 NA   
    #> 5 0.270 NA   
    #> 6 0.608 NA
    

    这表明我们需要改用日期解析器。要修复调用,首先将列规范复制并粘贴到原始调用中:

    challenge <- read_csv(
      readr_example("challenge.csv"), 
      col_types = cols(
        x = col_double(),
        y = col_logical()
      )
    )
    

    然后可以通过y指定y日期列来修复列的类型:

    challenge <- read_csv(
      readr_example("challenge.csv"), 
      col_types = cols(
        x = col_double(),
        y = col_date()
      )
    )
    tail(challenge)
    #> # A tibble: 6 x 2
    #>       x y         
    #>   <dbl> <date>    
    #> 1 0.805 2019-11-21
    #> 2 0.164 2018-03-29
    #> 3 0.472 2014-08-04
    #> 4 0.718 2015-08-16
    #> 5 0.270 2020-02-04
    #> 6 0.608 2019-01-06
    

    每个parse_xyz()函数都有对应的col_xyz()函数。当数据已经在 R 中的字符向量中时使用parse_xyz();你在使用col_xyz()的时候,你要告诉readr如何加载数据。

    我强烈建议自己提供col_types,从 readr 提供的打印输出中构建。这可确保您拥有一致且可重现的数据导入脚本。如果您依赖默认的猜测那么您的数据可能发生变化。如果您想通过readr 将继续读入它,请使用stop_for_problems(): 如果有任何解析问题,它将抛出错误并停止您的脚本。

    4.3 其他方法

    还有一些其他的通用方法可以帮助您解析文件:

    • 在前面的示例中,我们只是走运了:如果我们只查看比默认值多一行的行,我们可以一次性正确解析:

      challenge2 <- read_csv(readr_example("challenge.csv"), guess_max = 1001)
      #> 
      #> ── Column specification ────────────────────────────────────────────────────────
      #> cols(
      #>   x = col_double(),
      #>   y = col_date(format = "")
      #> )
      challenge2
      #> # A tibble: 2,000 x 2
      #>       x y         
      #>   <dbl> <date>    
      #> 1   404 NA        
      #> 2  4172 NA        
      #> 3  3004 NA        
      #> 4   787 NA        
      #> 5    37 NA        
      #> 6  2332 NA        
      #> # … with 1,994 more rows
      
    • 有时,如果您将所有列作为字符向量读取,则更容易诊断问题:

      challenge2 <- read_csv(readr_example("challenge.csv"), 
        col_types = cols(.default = col_character())
      )
      

      这与type_convert()结合使用特别有用,它将解析启发式应用于数据框中的字符列。

      df <- tribble(
        ~x,  ~y,
        "1", "1.21",
        "2", "2.32",
        "3", "4.56"
      )
      df
      #> # A tibble: 3 x 2
      #>   x     y    
      #>   <chr> <chr>
      #> 1 1     1.21 
      #> 2 2     2.32 
      #> 3 3     4.56
      
      # Note the column types
      type_convert(df)
      #> 
      #> ── Column specification ────────────────────────────────────────────────────────
      #> cols(
      #>   x = col_double(),
      #>   y = col_double()
      #> )
      #> # A tibble: 3 x 2
      #>       x     y
      #>   <dbl> <dbl>
      #> 1     1  1.21
      #> 2     2  2.32
      #> 3     3  4.56
      
    • 如果您正在读取一个非常大的文件,您可能希望设置n_max为一个较小的数字,例如 10,000 或 100,000。

    • 如果您遇到主要的解析问题,有时更容易读取带有read_lines()的行字符向量,甚至是长度为 1 的字符向量read_file()

    5 写入文件

    readr 还带有两个用于将数据写回磁盘的函数:write_csv()write_tsv(). 这两个函数都通过以下方式输出文件:

    • 始终以 UTF-8 编码字符串。

    • 以 ISO8601 格式保存日期和日期时间,以便在其他地方轻松解析。

    如果要将 csv 文件导出到 Excel,请使用write_excel_csv()-这会在文件开头写入一个特殊字符(“字节顺序标记”),告诉 Excel 您正在使用 UTF-8 编码。

    最重要的参数是x(要保存的数据框)和path(保存它的位置)。您还可以指定缺失值的写入方式na,以及append是否要写入现有文件。

    write_csv(challenge, "challenge.csv")
    

    注意保存到csv时类型信息丢失:

    challenge
    #> # A tibble: 2,000 x 2
    #>       x y         
    #>   <dbl> <date>    
    #> 1   404 NA        
    #> 2  4172 NA        
    #> 3  3004 NA        
    #> 4   787 NA        
    #> 5    37 NA        
    #> 6  2332 NA        
    #> # … with 1,994 more rows
    write_csv(challenge, "challenge-2.csv")
    read_csv("challenge-2.csv")
    #> 
    #> ── Column specification ────────────────────────────────────────────────────────
    #> cols(
    #>   x = col_double(),
    #>   y = col_logical()
    #> )
    #> # A tibble: 2,000 x 2
    #>       x y    
    #>   <dbl> <lgl>
    #> 1   404 NA   
    #> 2  4172 NA   
    #> 3  3004 NA   
    #> 4   787 NA   
    #> 5    37 NA   
    #> 6  2332 NA   
    #> # … with 1,994 more rows
    

    这使得 CSV 缓存临时结果有点不可靠——每次加载时都需要重新创建列规则。有两种选择:

    1. write_rds()read_rds()是围绕base函数readRDS()saveRDS()的统一包装。这些以 R 的自定义二进制格式存储数据,称为 RDS:

      write_rds(challenge, "challenge.rds")
      read_rds("challenge.rds")
      #> # A tibble: 2,000 x 2
      #>       x y         
      #>   <dbl> <date>    
      #> 1   404 NA        
      #> 2  4172 NA        
      #> 3  3004 NA        
      #> 4   787 NA        
      #> 5    37 NA        
      #> 6  2332 NA        
      #> # … with 1,994 more rows
      
    2. Feather 包实现了一种可以跨编程语言共享的快速二进制文件格式:

      library(feather)
      write_feather(challenge, "challenge.feather")
      read_feather("challenge.feather")
      #> # A tibble: 2,000 x 2
      #>       x      y
      #>   <dbl> <date>
      #> 1   404   <NA>
      #> 2  4172   <NA>
      #> 3  3004   <NA>
      #> 4   787   <NA>
      #> 5    37   <NA>
      #> 6  2332   <NA>
      #> # ... with 1,994 more rows
      

    Feather 往往比 RDS 更快,并且可以在 R 之外使用。RDS 支持列表。

    6 其他类型的数据

    要将其他类型的数据导入 R,我们建议从下面列出的 tidyverse 包开始。它们当然不是最好的方式,但它们是一个很好的起点。对于矩形数据:

    • Have读取 SPSS、Stata 和 SAS 文件。

    • readxl读取 excel 文件(包括.xls.xlsx)。

    • DBI以及特定于数据库的后端(例如 RMySQLRSQLiteRPostgreSQL等)允许您针对数据库运行 SQL 查询并返回数据框。

    对于分层数据:对 json使用jsonlite(由 Jeroen Ooms),对 XML 使用xml2。Jenny Bryan 在https://jennybc.github.io/purrr-tutorial/ 有非常好的示例。

    对于其他文件类型,可以查看R data import/export manual
    rio包。

    相关文章

      网友评论

          本文标题:6.数据导入

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