将SAS sas7bdat数据读入R中

Mic*_*ico 28 r r-faq

R有哪些选项可以将本机SAS格式的文件读sas7bdat入R?

NCES共同核心,例如,含有以这种格式保存的数据文件的广泛库.具体而言,让我们专注于试图在1997-98年从LEA Universe 读取这个文件,其中包含从A到I开始的所有州的实体的教育机构级人口统计数据.

以下是SAS对数据的预览:

sas_preview

将这些数据导入R环境的最简单方法是什么?我没有任何可用的SAS版本,也不愿意支付,所以简单地将其转换为.csv将是一件麻烦事.

Mic*_*ico 44

sas7bdat工作得很好,但所有我一直在寻找的一个文件(特别是,这一次); 在向sas7bdat开发人员Matthew Shotwell 报告错误时,他还指出了我haven在R中的Hadley 包的方向,这也有一个read_sas方法.

这种方法优越有两个原因:

1)阅读上面链接的文件没有任何问题2)它(我说的)快得多read.sas7bdat.这是一个快速基准(在这个文件上,比其他文件小)证据:

microbenchmark(times=10L,
               read.sas7bdat("psu97ai.sas7bdat"),
               read_sas("psu97ai.sas7bdat"))

Unit: milliseconds
                              expr        min         lq       mean     median         uq        max neval cld
 read.sas7bdat("psu97ai.sas7bdat") 66696.2955 67587.7061 71939.7025 68331.9600 77225.1979 82836.8152    10   b
      read_sas("psu97ai.sas7bdat")   397.9955   402.2627   410.4015   408.5038   418.1059   425.2762    10  a 
Run Code Online (Sandbox Code Playgroud)

没错 - haven::read_sas平均花费的时间比平均减少99.5%sas7bdat::read.sas7bdat.

小更新

我以前无法弄清楚这两种方法是否产生了相同的数据(即,两者在读取数据时都具有相同的保真度),但最终还是这样做了:

# Keep as data.tables
sas7bdat <- setDT(read.sas7bdat("psu97ai.sas7bdat"))
haven <- setDT(read_sas("psu97ai.sas7bdat"))

# read.sas7bdat prefers strings as factors,
#   and as of now has no stringsAsFactors argument
#   with which to prevent this
idj_factor <- sapply(haven, is.factor)

# Reset all factor columns as characters
sas7bdat[ , (idj_factor) := lapply(.SD, as.character), .SDcols = idj_factor]

# Check equality of the tables
all.equal(sas7bdat, haven, check.attributes = FALSE)
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

但请注意,read.sas7bdat该文件保留了大量属性列表,可能是SAS的延续:

str(sas7bdat)
# ...
# - attr(*, "column.info")=List of 70
#   ..$ :List of 12
#   .. ..$ name  : chr "NCESSCH"
#   .. ..$ offset: int 200
#   .. ..$ length: int 12
#   .. ..$ type  : chr "character"
#   .. ..$ format: chr "$"
#   .. ..$ fhdr  : int 0
#   .. ..$ foff  : int 76
#   .. ..$ flen  : int 1
#   .. ..$ label : chr "UNIQUE SCHOOL ID (NCES ASSIGNED)"
#   .. ..$ lhdr  : int 0
#   .. ..$ loff  : int 44
#   .. ..$ llen  : int 32
# ...
Run Code Online (Sandbox Code Playgroud)

所以,如果你任何机会需要这些属性(例如我知道某些人特别热衷于labels),或许read.sas7bdat毕竟是你的选择.


Ann*_*nna 8

自2018年1月18日起,避风港 R库将sas和stata数据集加载到R环境中.在R中,简单地说:

library(haven)
data <- read_sas("C:/temp/mysasdataset.sas7bdat")
View(data)
Run Code Online (Sandbox Code Playgroud)

您也可以在R studio中手动加载数据.在环境窗格中,选择

导入数据集>来自SAS ...

选择文件位置,然后单击"导入"


Phi*_*hil 6

问题

问题看起来像您尝试使用的文件格式不正确.具体而言,空白单元格未编码(R使用NA),但只是留空.当尝试加载制表符分隔文件时,这会为R产生问题,因为R认为列数不正确.

使用SAS文件的解决方法

我找到了一个解决方法,通过使用sas7bdat包加载SAS文件,然后将空白单元格("")重新编码为NA:

install.packages("sas7bdat")
require("sas7bdat")
download.file("http://nces.ed.gov/ccd/Data/zip/ag121a_supp_sas.zip",
              destfile = "sas.zip")
unzip("sas.zip")
sas <- read.sas7bdat(file = "ag121a_supp.sas7bdat", debug = FALSE)
sas[sas == ""] <- NA
Run Code Online (Sandbox Code Playgroud)

但是,要注意这个方法有两个问题:

  1. 这很慢(见评论)
  2. sas7bdat包装目前在其作者撰写时被认为是实验性的.因此它可能无法加载所有sas文件,我会在使用前检查它是否彻底解决了不一致问题.

非R解决方案

这不是规范的,但您也可以下载制表符分隔的文件,在LibreOffice Calc中打开它们(Microsoft Excel似乎搞砸了),并通过搜索""和替换来查找和替换所有文件NA.

  • 刚从Shotwell教授那里听到,他指出`haven`基本上是一个`C`端口进入`R`包,而`sas7bdat`完全用`R`编写,这解释了缓慢. (2认同)