搜索
查看: 998|回复: 2

[R] 慧美——R for data science 第8章 使用readr进行数据导入

[复制链接]

39

主题

40

帖子

292

积分

中级会员

Rank: 3Rank: 3

积分
292
发表于 2018-11-10 16:16:57 | 显示全部楼层 |阅读模式



R for data science  第8章  使用readr进行数据导入
8.1  简介
  • 在本章中学习如何将纯文本格式的矩形文件读入 R
  • 使用 readr 包将平面文件加载到 R 中
    library(tidyverse)
8.2  入门
  • readr 的多数函数用于将平面文件转换为数据框。
    • read_csv() 读取逗号分隔文件、read_csv2() 读取分号分隔文件、read_tsv() 读取制表符分隔文件、read_delim() 可以读取使用任意 分隔符的文件。
    • read_fwf() 读取固定宽度的文件。既可以使用 fwf_widths() 函数按照宽度来设定域,也可 以使用 fwf_positions() 函数按照位置来设定域。read_table() 读取固定宽度文件的一种常 用变体,其中使用空白字符来分隔各列。
    • CSV
      • CSV 文件是数据存储最常用的形式之一
      • read_csv() 函数的第一个参数是最重要的,该参数是要读取的文件的路径
      • 当运行 read_csv() 时,它会打印一份数据列说明,给出每个列的名称和类型
        heights<-read_csv("data/heights.csv") #> Parsed with column specification:
        #> cols(
            #>   earn = col_double(),
            #>   height = col_double(),
            #>   sex = col_character(),
            #>   race = col_character()
            #> )
      • 提供一个行内 CSV 文件
        file:///Users/huimei/Library/Application%20Support/typora-user-images/image-20181110104251517.png?lastModify=1541837725

    • 有时文件开头会有好几行元数据。你可以使用skip = n来跳过前n行;或者使用comment = "#" 来丢弃所有以 # 开头的行
    • 数据没有列名称。可以使用col_names = FALSE来通知read_csv()不要将第一行作为列标题,而是将各列依次标注为 X1 至 Xn
      # "\n" 是非常便捷的快捷方式,用于添加新行。
    • 可以向 col_names 传递一个字符向量,以用作列名称


  • 另一个通常需要修改的选项是 na。它设定使用哪个值(或哪些值)来表示文件中的缺失值

# NA,有坑没萝卜;NULL, 没坑;0,有坑且坑里有萝卜
  • 使用 readr 中的函数的优势
    • 比基础模块中的函数速度更快
    • 可以生成 tibble,并且不会将字符向量转换为因子,不使用行名称,也不会随意改动列名称。
    • 更易于重复使用。R 基础包中的函数会继承操作系统的功能,并依赖环境变量,因此,可以在你的计算机上正常运行的代码在导入他人计算机时,不一定能正常运行。


8.3 解析向量
  • parse_*() 函数族。这些函数接受一个字符向量,并返回一个特定向量,如逻辑、整数或日期向量
  • parse_*() 函数族的用法是一致的。第一个参数是需要解析的字符向量,na 参数设定了哪些字符串应该当作缺失值来处理

  • 解析失败的值在输出中是以缺失值的形式存在的
  • 如果解析失败的值很多,那么就应该使用 problems() 函数来获取完整的失败信息集合。这个函数会返回一个 tibble,你可以使用 dplyr 包来进行处理
  • 在解析函数的使用方面,最重要的是要知道有哪些解析函数,以及每种解析函数用来处理哪种类型的输入。
    • parse_logical() 和 parse_integer() 函数分别解析逻辑值和整数。
    • parse_double() 是严格的数值型解析函数,parse_number() 则是灵活的数值型解析函数。
    • parse_character() 字符编码使得这个函数变得重要
    • parse_factor() 函数可以创建因子,R 使用这种数据结构来表示分类变量,该变量具有 固定数目的已知值。
    • parse_datetime()、parse_date() 和 parse_time() 函数可以解析不同类型的日期和时间。

  • 数值解析的复杂性
    • 世界各地的人们书写数值的方式不尽相同。例如,有些国家使用 . 来分隔实数中的整数 和小数部分,而有些国家则使用 ,
    • 数值周围经常有表示某种意义的其他字符,如 $1000 或 10%。
    • 数值经常包含“分组”,以便更易读,如 1 000 000,而且世界各地用来分组的字符也不尽相同。

    • readr 使用了“地区”这一概念,这是可以按照不同地区设置解析选项的一个对象。在解析数值时,最重要的选项就是用来表示小数点的字符。通过创建一个新的地区对象并设定 decimal_mark 参数,可以覆盖 . 的默认值


  • parse_number() 解决了第二个问题:它可以忽略数值前后的非数值型字符。这个函数适合处理货币和百分比,也可以提取嵌在文本中的数值
  • 组合使用 parse_number() 和地区设置可以解决最后一个问题,因为 parse_number() 可以忽略“分组符号”

  • 在 R 中,我们可以使用 charToRaw() 函数获得一个字符串的底层表示

  • 从十六进制数到字符的这种映射称为编码,这个示例中的编码方式称为 ASCII。ASCII 可以非常好地表英        文字符
    • UTF-8 可以为现在人类使用的所有字符进行编码,同时还支持很多特殊字符。readr 全面支持 UTF-8:当读取数据时,它假设数据是 UTF-8 编码的,并总是使用 UTF-8编码写入数据。这是非常好的默认方式,但对于从不支持 UTF-8 的那些旧系统中产生的数据则无能为力。遇到这种情况时,你的字符串打印出来就是一堆乱码。
    • 要想解决这个问题,需要在 parse_character() 函数中设定编码方式
    • Latin1(即 ISO-8859-1,用于西欧语言)和 Latin2(即 ISO-8859-2,用于东欧语言)是两种常用的编码方式。字节 b1 在 Latin1中表示“±”,但在 Latin2 中则表示“ą”!好在现在有一种几乎所有语言都支持的标准
    • guess_encoding() 的第一个参数可以是一个文件路径,也可以是一个原始向量(适用于字符串已经在 R 中的情况)
    • parse_datetime() 期待的是符合 ISO 8601 标准的日期时间。ISO 8601 是一种国际标准, 其中日期的各个部分按从大到小的顺序排列,即年、月、日、小时、分钟、秒
    • file:///Users/huimei/Library/Application%20Support/typora-user-images/image-20181110145546269.png?lastModify=1541837725
    • parse_date() 期待的是四位数的年份、一个 - 或 /、月、一个 - 或 /,然后是日


  • parse_time() 期待的是小时、:、分钟、可选的 : 和秒,以及一个可选的 a.m./p.m. 标识符


%Y(4位数)。
%y(2位数;00-69→ 2000-2069、70-99→ 1970-1999)。 月
%m(2 位数)。 %b(简写名称,如 Jan)。 %B(完整名称,如 January)。

%e(2位数) 时间
%H(0-23小时)。
%I(0-12 小时,必须和 %p一起使用)。 %p(表示 a.m./p.m.)。
%M(分钟)。
%S(整数秒)。
%OS(实数秒)。
%Z(时区,America/Chicage这样的名称)。注意,要当心缩写。如果你是美国人,注意 EST是加拿大没有夏时制的一个时区。它表示东部标准时间!我们还会在 12.5节中继 续讨论这个话题。
%z(与国际标准时间的时差,如 +0800)。 非数值字符
%.(跳过一个非数值字符)。
%*(跳过所有非数值字符)。 8.4 解析文件• readr如何自动猜出文件每列的数据类型。
• 如何修改默认设置。
readr 使用一种启发式过程来确定每列的类型:先读取文件的前 1000 行,然后使用(相对保守的)某种启发式算法确定每列的类型。可以使用字符向量模拟这个过程,先使用 guess_parser() 函数返回 readr 最可信的猜测,接着 parse_guess() 函数使用这个猜测来解析列
这个启发式过程会尝试以下每种数据类型,直至找到匹配的类型。
逻辑值
只包括 F、T、FALSE 和 TRUE。
整数
只包括数值型字符(以及 -)。
双精度浮点数
只包括有效的双精度浮点数(也包括 4.5e-5 这样的数值)。
数值
只包括带有分组符号的有效双精度浮点数。
时间
与默认的 time_format 匹配的值。
日期
与默认的 date_format 匹配的值。
日期时间
符合 ISO 8601 标准的任何日期。 如果以上类型均不匹配,那么这一列就还是一个字符串向量。
  • 两个主要问题
    • readr 猜测出的类型不足以代表整个文件,  前1000行可能是一种特殊情况
    • 列中可能含有大量缺失值。

  • 解决方案
    • 使用 problems() 函数明确地列出这些失败记录,以便更加深入地探究其中的问题
    • 复制列类型并将其粘贴到初始调用中
      challenge<-read_csv(
            readr_example("challenge.csv"),
            col_types=cols(
              x=col_integer(),
              y=col_character()
            )
      )
    • 接着修改 x 列的类型
      challenge<-read_csv(
            readr_example("challenge.csv"),
            col_types=cols(
              x=col_double(),
              y=col_character()
            )
      )
  • 有时如果将所有列都作为字符向量读入的话,会更容易诊断出问题
    challenge2<-read_csv(readr_example("challenge.csv"),
          col_types=cols(.default=col_character())
    )
  • 如果遇到严重的解析问题,有时使用 read_lines() 函数按行读入字符向量会更容易,甚至可以使用 read_file() 函数读入一个长度为 1 的字符向量。

8.5 写入文件
  • 用于将数据写回到磁盘:write_csv() 和 write_ tsv()。
    • 这两个函数输出的文件能够顺利读取的概率更高
    • 总是使用 UTF-8 对字符串进行编码
    • 使用 ISO 8601 格式来保存日期和日期时间数据,以便这些数据不论在何种环境下都更容易解析。

  • 如果想要将 CSV 文件导为 Excel 文件,可以使用 write_excel_csv() 函数,该函数会在文件开头写入一个特殊字符(字节顺序标记),告诉 Excel 这个文件使用的是 UTF-8 编码
  • 函数中最重要的参数是x(要保存的数据框) 和path(保存文件的位置)。可以使用na参数设定如何写入缺失值。想要追加到现在的文件,需要设置append参数
  • 暂存临时结果
    • write_rds() 和 read_rds() 函数是对基础函数 readRDS() 和 saveRDS() 的统一包装。前者可以将数据保存为 R 自定义的二进制格式,称为 RDS 格式
      write_rds(challenge, "challenge.rds")
      read_rds("challenge.rds")
    • feather 包实现了一种快速二进制格式,可以在多个编程语言间共享


library(feather)
write_feather(challenge, "challenge.feather") read_feather("challenge.feather")
  • 两种方式对比:feather比RDS更快,且可以在R之外使用。RDS支持列表列,feather还不行。

8.6 其他类型的数据
  • heaven可以读取SPSS、Stata和SAS文件
  • readxl可以读取Excel文件(.xls和xlsx均可)
  • 配合专用的数据库后端程序(如RMySQL,RSQLite,RPostgreSQL等)






上一篇:第16章
下一篇:想用Deseq2来做表达差异分析,但是老师执着于FPKM
回复

使用道具 举报

634

主题

1182

帖子

4030

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4030
发表于 2018-11-13 09:41:00 | 显示全部楼层
你写的很棒
你这个问题很复杂,需要打赏,请点击 http://www.bio-info-trainee.com/donate 进行打赏,谢谢
回复 支持 反对

使用道具 举报

39

主题

40

帖子

292

积分

中级会员

Rank: 3Rank: 3

积分
292
 楼主| 发表于 2018-11-27 08:10:36 | 显示全部楼层

谢谢Jimmy老师,争取能进入Jimmy老师的VIP群
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|生信技能树 ( 粤ICP备15016384号  

GMT+8, 2019-10-22 23:01 , Processed in 0.034361 second(s), 26 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.