Экспорт данных из R в SPSS: проблема меток (VARIABLE & VALUE LABELS) и частичное решение

Странно, что никто до сих пор не озадачился и не сделал нормально работающий импорт-экспорт файлов SPSS в R.

Что я имею в виду? Представим себе файл в SPSS, содержащий единственную переменную «yes», с VARIABLE LABEL «Yes or no», VALUE LABELS {1=»Yes», 0=»No»}. В переменной всего четыре значения.

При использовании функции read.spss из пакета foreign, мы имеем два варианта действий.

require('foreign')
require('Hmisc')
yesT <- read.spss("yes.sav", use.value.labels = TRUE, to.data.frame = TRUE) yesF <- read.spss("yes.sav", use.value.labels = FALSE, to.data.frame = TRUE)


Результаты выполнения этих двух вариантов будут такие:

yesT
yes
1 Yes
2 No
3 No
4 Yes

yesF
yes
1 1
2 0
3 0
4 1

В первом случае мы имеем фактор с двумя уровнями, во втором - числовой вектор. То есть у нас есть либо метки значений, либо сами значения. Но не всё так печально. За счёт использования пакета Hmisc, структура данных несколько более сложная и включает всю необходимую информацию:

str(yesF)
'data.frame': 4 obs. of 1 variable:
$ yes: atomic 1 0 0 1
..- attr(*, "value.labels")= Named num 1 0
.. ..- attr(*, "names")= chr "Yes" "No"
- attr(*, "variable.labels")= Named chr "Yes or No"
..- attr(*, "names")= chr "yes"
- attr(*, "codepage")= int 1251

Вроде бы всё нормуль. Но вот как сохранить обратно файл в SPSS? Стандартное сохранение в SPSS из пакета foreign
write.foreign(yesF, "d:/yes.txt", "d:/yes.sps", package="SPSS")
генерирует такой вот "конструктор" из двух файлов - с данными и набором команд импорта. Но никаким образом не сохраняет ни меток переменных, ни меток значений, вот содержание yes.sps:

DATA LIST FILE= "d:/yes.txt" free (",")
/ yes .

VARIABLE LABELS
yes "yes"
.

EXECUTE.

Однако один активист подготовил функцию, заменяющую стандартную, которая немного спасает:


adQuote <- function(x) {paste("\"", x, "\"", sep = "")} write.SPSS <- function (df, datafile, codefile, varnames = NULL) { dfn <- lapply(df, function(x) if (is.factor(x)) as.numeric(x) else x) write.table(dfn, file = datafile, row = FALSE, col = FALSE) if(is.null(attributes(df)$variable.labels)) varlabels <- names(df) else varlabels <- attributes(df)$variable.labels if (is.null(varnames)) { varnames <- abbreviate(names(df), 8) if (any(sapply(varnames, nchar) > 8))
stop("I cannot abbreviate the variable names to eight or fewer letters")
if (any(varnames != names(df)))
warning("some variable names were abbreviated")
}
cat("DATA LIST FILE=", dQuote(datafile), " free\n", file = codefile)
cat("/", varnames, " .\n\n", file = codefile, append = TRUE)
cat("VARIABLE LABELS\n", file = codefile, append = TRUE)
cat(paste(varnames, adQuote(varlabels), "\n"), ".\n", file = codefile,
append = TRUE)
factors <- sapply(df, is.factor) if (any(factors)) { cat("\nVALUE LABELS\n", file = codefile, append = TRUE) for (v in which(factors)) { cat("/\n", file = codefile, append = TRUE) cat(varnames[v], " \n", file = codefile, append = TRUE) levs <- levels(df[[v]]) cat(paste(1:length(levs), adQuote(levs), "\n", sep = " "), file = codefile, append = TRUE) } cat(".\n", file = codefile, append = TRUE) } cat("\nEXECUTE.\n", file = codefile, append = TRUE) }

Однако, вот что получается с её использованием:
write.SPSS(yesF, "d:/yes.txt", "d:/yes.sps")
DATA LIST FILE= “d:/yes.txt” free
/ yes .

VARIABLE LABELS
yes "Yes or No"
.

EXECUTE.

То есть метка переменной появилась, а меток значений нет. Дело в том, что эта функция ловит значения из факторов R, а импортированные данные - вектор. Но у нас был "первый путь", когда при импорте из SPSS наша переменная становилась фактором. Что будет, если сохранить тот, первый файл?
write.SPSS(yesT, "d:/yes.txt", "d:/yes.sps")
DATA LIST FILE= “d:/yes.txt” free
/ yes .

VARIABLE LABELS
yes "Yes or No"
.

VALUE LABELS
/
yes
1 "No"
2 "Yes"
.
EXECUTE.

О! Появляются и метки значений. Но вместо 0 и 1, появились 1 и 2. Нумерация в функции делается по уровням факторов, начиная от 1. Можно подработать немного напильником, сделав так, чтобы нумерация начиналась с 0, но полностью проблемы это не решает. Необходима доработка функции таким образом, чтобы сохранялись исходные метки значений. Кроме того, функция не хочет работать с русскими именами переменных.

About the Author: Владимир Волохонский
Владимир Волохонский - психолог, выпускник факультета психологии СПбГУ, с 2002 по 2011 преподавал там же дисциплины "Математические методы в психологии", "Дизайн психологического исследования", "Психометрия" и др. С 2011 года - индивидуальный предприниматель.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *