将 SAS sas7bdat 数据读取到 R 中

Read SAS sas7bdat data into R

提问人: 提问时间:5/3/2015 最后编辑:9 revsMichaelChirico 更新时间:10/18/2020 访问量:100289

问:

R 有哪些选项可用于将本机 SAS 格式的文件读取到 R 中?sas7bdat

例如,NCES Common Core 包含以这种格式保存的大量数据文件存储库。具体而言,让我们专注于尝试阅读 1997-98 年 LEA Universe 中的这个文件,其中包含从 A 到 I 的所有州实体的教育机构级别的人口统计数据。

以下是 SAS 对数据的预览:

A screenshot from SAS showing 15 rows of data and the first 5 columns

将此数据引入 R 环境的最简单方法是什么?我没有任何可用的SAS版本,也不愿意付费,因此简单地将其转换为.csv会很麻烦。

R-常见问题

评论

0赞 rawr 3/22/2016
当然,我已经用了好几年了,它们总是看起来很挑剔或缺乏我需要的一些功能,并且有几种可供选择(而且更多不断涌现),所以有一个 wiki 来解决这样一个常见的问题会很好。我几乎放弃了“读取 sas 数据集”包——我从来没有想过如何应用格式,我只是再试一次,它给了我一个错误。如果必须的话,我会使用包装器来读取 sas 数据集的目录并返回数据帧列表,尽管它需要一个有效的 sas,但一直对我有用sas7bdathavenHmisc::sas.get
0赞 MichaelChirico 3/22/2016
@rawr如果发现时间和文件的公开性,请添加一个答案,举例说明:)的不足之处在这种情况下,虽然需要一个有效的SAS,但了解替代方案是有帮助的。havenHmisc
0赞 rawr 3/25/2016
haven读取文件就好了。我还需要这些格式,因为我从 sas 获得的大量数据基本上都是未格式化的。当不给我一个模糊的错误时,它并没有真正应用格式——只是将它们保留为需要更多用户跑腿工作的属性——不多,不难,但有出错的空间。 (以及我使用的包装器 fn)在 sas 中执行所有这些操作(可选)并返回格式化的数据框havenHmisc::sas.get
1赞 rawr 3/25/2016
我遇到的另一个问题是,如果您尝试使用在 Windows 上的 Unix/Linux 上创建的目录(反之亦然),则会出现更多错误。但是,如果您有 proc 格式代码,则可以使用 SAS 创建平台本机的格式目录。由于 Haven 需要目录,如果您只有 proc 格式代码,您似乎是 SOL

答:

7赞 3 revs, 2 users 87%Phil #1

问题

问题似乎是您尝试使用的文件格式不佳。具体来说,空白单元格没有被编码(使用),而只是留空。当尝试加载制表符分隔的文件时,这会给 R 带来问题,因为 R 认为列数不正确。RNA

使用 SAS 文件的解决方法

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

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

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

  1. 它很慢(见评论)
  2. sas7bdat在撰写本文时,软件包目前被其作者视为实验性软件包。因此,它可能不会加载所有 sas 文件,我会在使用前彻底检查它所做的不一致。

非 R 解决方案

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

评论

0赞 MichaelChirico 5/3/2015
这当然有效;你觉得它慢吗?读取一个文件需要 ~3 分钟——用户在 18,000 行中基本上是闻所未闻的!好的部分是,我只需要加载它们一次,就可以将它们保存到 。data.tablecsvR
0赞 Phil 5/4/2015
我确实觉得它很慢,是的。此外,我会小心地在输入后彻底检查数据框,因为在撰写此评论时,其作者将其视为实验性数据框。但是,如果它有效......sas7bdat
2赞 MichaelChirico 5/6/2015
刚才又从肖特韦尔教授那里听到的,他指出,基本上是一个移植到一个包中,而完全是用 写在 中,这解释了迟钝的原因。havenCRsas7bdatR
0赞 isomorphismes 9/19/2017
就您的非 R 解决方案而言:非常好,您可以在命令行中使用,加上 ,在没有 gui 的情况下实现相同的结果。localcsed
57赞 6 revsMichaelChirico #2

sas7bdat除了我正在查看的一个文件(特别是这个文件)之外,其他所有文件都工作正常;在向开发人员 Matthew Shotwell 报告错误时,他还向我指出了 R 中 Hadley 包的方向,该包也有一个方法。sas7bdathavenread_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 

没错,(平均)花费的时间比 少 99.5%。haven::read_sassas7bdat::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

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

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
# ...

所以,如果你有机会需要这些属性(例如,我知道有些人特别热衷于s),也许毕竟是你的选择。labelread.sas7bdat

评论

1赞 Chris Holbrook 7/16/2019
避风港 (v. 2.1.1) 似乎保留了“标签”属性。From : “变量标签存储在每个变量的”label“属性中。它不会打印在控制台上,但 RStudio 查看器将显示它。?haven::read_sas
0赞 Vincent 9/8/2022
如果要访问这些属性,只需键入 。attributes(df)
13赞 cacti5 #3

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

library(haven)
data <- read_sas("C:/temp/mysasdataset.sas7bdat")
View(data)

还可以在 R Studio 中手动加载数据。在环境窗格中,选择

从 SAS 导入数据集>...

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

评论

0赞 MichaelChirico 5/2/2018
您能澄清一下2018年有什么新变化吗?我在下面的答案中广泛地介绍了read_sas。如果您认为该回复需要澄清,请随时编辑该回复,因为它是一个社区维基。
0赞 Jan Marvin #4

另一个选择可能是我的 readsas 包。语法类似于包的语法和 read-series 的其他语法。导入的数据以 with 属性的形式返回。该软件包是从头开始编写的,具有对未压缩和压缩文件的读取支持。foreigndata.frame()sas7bdat

尽管它已经过很多测试,但该软件包仍处于早期开发阶段。

library(readsas)
dat <- read.sas("psu97ai.sas7bdat")