Считать данные SAS sas7bdat в R

Какие возможности есть у R для чтения файлов в собственном формате SAS, sas7bdatв R?

Например, NCES Common Core содержит обширное хранилище файлов данных, сохраненных в этом формате. Для конкретности давайте сосредоточимся на том, чтобы попытаться прочитать в этом файле из LEA Universe в 1997-98 гг., Который содержит демографические данные на уровне образовательного агентства для организаций во всех штатах, начиная с A по I.

Вот предварительный просмотр данных SAS:

sas_preview

Какой самый простой способ перенести эти данные в мою среду R? У меня нет какой-либо версии SAS и я не собираюсь платить, поэтому просто конвертировать ее в.csv было бы хлопотно.

3 ответа

Решение

sas7bdat отлично работал для всех, кроме одного файла, который я просматривал (в частности, этот); в сообщении об ошибке sas7bdat разработчик, Мэтью Шотвелл, он также указал мне в направлении Хэдли haven пакет в R, который также имеет 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 

Вот так--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

Тем не менее, обратите внимание, что 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
# ...

Так что, если случайно вам понадобятся эти атрибуты (я знаю, что некоторые люди особенно заинтересованы в labelс, например), возможно read.sas7bdat это вариант для вас в конце концов.

По состоянию на 18 января 2018 года библиотека убежища R будет загружать наборы данных sas и stata в среду R. В R просто:

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

Вы также можете загрузить данные вручную в R studio. В панели среды выберите

Импортировать набор данных> Из SAS...

Выберите местоположение файла и нажмите "Импорт"

проблема

Проблема в том, что файлы, которые вы пытаетесь использовать, плохо отформатированы. В частности, пустые ячейки не кодируются (R использования NA) но просто остаются пустыми. При попытке загрузить файл с разделителями табуляции это создает проблемы для R, который считает, что количество столбцов неверно.

Обходной путь с использованием файлов SAS

Я нашел обходной путь, загрузив файл SAS с помощью sas7bdat пакет, а затем перекодировать пустые ячейки ("") как 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

Однако следует помнить о двух проблемах этого метода:

  1. Это медленно (см. Комментарии)
  2. sas7bdat Пакет в настоящее время считается экспериментальным на момент написания его автором. Поэтому он может не загружать все файлы sas, и я бы проверил те, которые он делает, на предмет несоответствий перед использованием.

Не R решение

Это не совсем канонично, но вы также можете скачать файлы с разделителями табуляции, открыть их в LibreOffice Calc (Microsoft Excel, похоже, все испортило), а также найти и заменить все, выполнив поиск "" и заменить на NA,

Другой вариант мог бы быть моим readsas пакет. Синтаксис аналогичен синтаксисуforeignпакет и другие из серии чтения. Импортированные данные возвращаются в видеdata.frame()с атрибутами. Пакет был написан с нуля и имеет поддержку чтения несжатых и сжатых файлов.sas7bdat файлы.

Несмотря на то, что он был много протестирован, пакет все еще находится на ранней стадии разработки.

library(readsas)
dat <- read.sas("psu97ai.sas7bdat")
Другие вопросы по тегам