#r #label #export #spss
#r #метка #экспорт #spss
Вопрос:
Мне нужно преобразовать имена, метки и атрибуты переменных файла SPSS (* .sav) (НЕ значения данных) в * .txt / * .csv в R. Предпочтительной структурой в R (для экспорта) является data.frame в этой форме, см. Пример ниже:
> new.label.dataframe
VARIABLE.NAME ATTRIBUTE LABEL
STATUS 1 Complete
STATUS 2 Screen out Q1
STATUS 3 Screen out Q5
SAMPLE 1 Kunín Hollandia (včetně černobílých)
SAMPLE 2 Mlýn Krajina
...etc.
Q2_1 NA dobré složení
Q2_1 NA Žádné konzervanty
Q2_1 NA lahodný
...etc.
После импорта данных в R с помощью haven() Я использовал библиотеку R sjlabelled() для извлечения меток:
library(haven)
mydata <- read_sav("DATA_FINAL.sav", encoding = NULL, user_na = FALSE)
library(sjlabelled)
lab <- get_labels(mydata, values=T):
str(lab)
> str(lab)
List of 762
$ ID : NULL
$ STATUS : Named chr [1:3] "Complete" "Screen out Q1" "Screen out Q5"
..- attr(*, "names")= chr [1:3] "1" "2" "3"
$ SAMPLE : Named chr [1:2] "Kunín Hollandia (včetně černobílých)" "Mlýn Krajina"
..- attr(*, "names")= chr [1:2] "1" "2"
$ ORDER : Named chr [1:2] "Kunín ==> Hollandia || Mlýn ==> Krajina" "Hollandia ==> Kunín || Krajina ==> Mlýn"
..- attr(*, "names")= chr [1:2] "1" "2"
$ Q1 : Named chr [1:6] "5x týdně nebo častěji" "1x – 4x týdně" "1x za dva týdny" "1x za měsíc" ...
..- attr(*, "names")= chr [1:6] "1" "2" "3" "4" ...
$ Q2_1 : chr [1:473] "dobré složení" "Žádné konzervanty" "lahodný" "Husty" ...
$ Q2_2 : chr [1:431] "prává chuť" "Žádné Přidatné látky" "vláčný" "Chutny" ...
$ Q2_3 : chr [1:311] "" "Žádná Zahušťovadla" "konzistentní" "Ovocny" ...
head(lab, 6)
> head(lab, 6)
$ID
NULL
$STATUS
1 2 3
"Complete" "Screen out Q1" "Screen out Q5"
$SAMPLE
1 2
"Kunín Hollandia (včetně černobílých)" "Mlýn Krajina"
$ORDER
1 2
"Kunín ==> Hollandia || Mlýn ==> Krajina" "Hollandia ==> Kunín || Krajina ==> Mlýn"
$Q1
1 2 3 4 5 6
"5x týdně nebo častěji" "1x – 4x týdně" "1x za dva týdny" "1x za měsíc" "1x za čtvrt roku" "Méně často"
$Q2_1
[1] "dobré složení" "Žádné konzervanty"
[3] "lahodný" "Husty"
[5] "Krémový" ""
[7] "Musi mi chutnat" "hustý"
[9] "Chutny" "Hustý"
[11] "vysoké procento tuku" "krémový"
Класс «lab» представляет собой список:
> class(lab)
[1] "list"
Обратите внимание, что переменная Q2_1 имеет только метки («dobre slozeni» и т.д.), Но не атрибуты (1,2,3 …).
Довольно легко извлечь векторы имен переменных, атрибутов и меток:
my.vars <- names(lab)
my.atts <- unlist(lapply(lab, attributes))
my.labs <- unlist(unname(lab))
…но их длины действительно отличаются:
> length(my.vars)
[1] 762
> length(my.atts)
[1] 1734
> length(my.labs)
[1] 4775
Лучшее, что я могу получить, приведено ниже — однако не очень удобно:
> lab.u <- data.frame(unlist(lab))
> head(lab.u, 20)
unlist.lab.
STATUS.1 Complete
STATUS.2 Screen out Q1
STATUS.3 Screen out Q5
SAMPLE.1 Kunín Hollandia (včetně černobílých)
SAMPLE.2 Mlýn Krajina
ORDER.1 Kunín ==> Hollandia || Mlýn ==> Krajina
ORDER.2 Hollandia ==> Kunín || Krajina ==> Mlýn
Q1.1 5x týdně nebo častěji
Q1.2 1x – 4x týdně
Q1.3 1x za dva týdny
Q2_11 dobré složení
Q2_12 Žádné konzervanty
Q2_13 lahodný
Пожалуйста, есть какие-либо подсказки по преобразованию «lab» в структуру, описанную выше, в начале этого сообщения?
Большое спасибо!
Зденек Скала
Ответ №1:
Вы могли бы написать небольшую Vectorize
общую функцию, которая очищает "label.table"
атрибуты ваших данных SPSS и выполняет обработку регистра для "factor"
(т. Е. С метками) или других классов (без меток). Я не уверен в преимуществах использования sjlabelled
package, поэтому я его не использую.
attFun <- Vectorize(function(x) {
if (is.factor(spss[[x]])) {
a <- sort(attributes(spss)$label.table[[x]])
cbind(VARIABLE.NAME=names(spss)[x], ATTRIBUTE=unname(a), LABEL=names(a))
} else {
u <- unique(spss[[x]])
cbind(VARIABLE.NAME=names(spss)[x], ATTRIBUTE=NA, LABEL=u)
}
}, SIMPLIFY=F)
Результат просто нужно rbind
отредактировать.
res <- do.call(rbind.data.frame, attFun(1:5))
res
# VARIABLE.NAME ATTRIBUTE LABEL
# 1 vehicle 1 car
# 2 vehicle 2 LGV
# 3 vehicle 3 SUV
# 4 vehicle 4 bus
# 5 vehicle 5 HGV
# 6 vehicle 6 taxi
# 7 vehicle 7 PTW
# 8 Colour 1 blue
# 9 Colour 2 red
# 10 Colour 3 silver/grey
# 11 Colour 4 white
# 12 Colour 5 black
# 13 Colour 6 green
# 14 Colour 9 other
# 15 Colour 99 unknown
# 16 hour <NA> 57600
# 17 hour <NA> 25200
# 18 hour <NA> 28800
# 19 hour <NA> 32400
# 20 hour <NA> 50400
# 21 hour <NA> 54000
# 22 hour <NA> 39600
# 23 hour <NA> 43200
# 24 hour <NA> 61200
# 25 hour <NA> 28800
# 26 hour <NA> 36000
# 27 hour <NA> 36000
# 28 hour <NA> 39600
# 29 hour <NA> 46800
# 30 hour <NA> 46800
# 31 Colour2 <NA> blue
# 32 Colour2 <NA> red
# 33 Colour2 <NA> unknown
# 34 Colour2 <NA> other
# 35 Colour2 <NA> silver/grey
# 36 Colour2 <NA> white
# 37 Colour2 <NA> black
# 38 Colour2 <NA> green
# 39 Distance_from_kerb <NA> 0.5
# 40 Distance_from_kerb <NA> 1
# 41 Distance_from_kerb <NA> 0.25
# 42 Distance_from_kerb <NA> 1.25
# 43 Distance_from_kerb <NA> 0.75
Пример данных:
spss <- foreign::read.spss("http://staff.bath.ac.uk/pssiw/stats2/PsychBike.sav")
spss[[4]] <- as.character(spss$Colour)
names(spss)[4] <- "Colour2"