Считать данные SAS sas7bdat в R
Какие возможности есть у R для чтения файлов в собственном формате SAS, sas7bdat
в R?
Например, NCES Common Core содержит обширное хранилище файлов данных, сохраненных в этом формате. Для конкретности давайте сосредоточимся на том, чтобы попытаться прочитать в этом файле из LEA Universe в 1997-98 гг., Который содержит демографические данные на уровне образовательного агентства для организаций во всех штатах, начиная с A по I.
Вот предварительный просмотр данных SAS:
Какой самый простой способ перенести эти данные в мою среду 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
Однако следует помнить о двух проблемах этого метода:
- Это медленно (см. Комментарии)
sas7bdat
Пакет в настоящее время считается экспериментальным на момент написания его автором. Поэтому он может не загружать все файлы sas, и я бы проверил те, которые он делает, на предмет несоответствий перед использованием.
Не R решение
Это не совсем канонично, но вы также можете скачать файлы с разделителями табуляции, открыть их в LibreOffice Calc (Microsoft Excel, похоже, все испортило), а также найти и заменить все, выполнив поиск ""
и заменить на NA
,
Другой вариант мог бы быть моим readsas
пакет. Синтаксис аналогичен синтаксисуforeign
пакет и другие из серии чтения. Импортированные данные возвращаются в видеdata.frame()
с атрибутами. Пакет был написан с нуля и имеет поддержку чтения несжатых и сжатых файлов.sas7bdat
файлы.
Несмотря на то, что он был много протестирован, пакет все еще находится на ранней стадии разработки.
library(readsas)
dat <- read.sas("psu97ai.sas7bdat")