Извлеките атрибут метки из "помеченных" столбцов тиббла из импорта в гавань из Stata
Хэдли Уикхем haven
Пакет, примененный к файлу Stata, возвращает столбец со многими столбцами типа "помечены". Вы можете увидеть это с помощью str(), например:
$ MSACMSZ :Class 'labelled' atomic [1:8491861] NA NA NA NA NA NA NA NA NA NA ...
.. ..- attr(*, "label")= chr "metropolitan area size (cmsa/msa)"
.. ..- attr(*, "labels")= Named int [1:7] 0 1 2 3 4 5 6
.. .. ..- attr(*, "names")= chr [1:7] "not identified or nonmetropolitan" "100,000 - 249,999" "250,000 - 499,999" "500,000 - 999,999" ...
Было бы хорошо, если бы я мог просто извлечь все эти помеченные векторы из факторов, но я сравнил длину атрибута меток с числом уникальных значений в каждом векторе, и иногда он длиннее, а иногда короче. Поэтому я думаю, что мне нужно посмотреть на все из них и решить, как обращаться с каждым в отдельности.
Поэтому я хотел бы извлечь значения атрибута метки в список. Однако эта функция:
labels93 <- lapply(cps_00093.df, function(x){attr(X, which="labels", exact=TRUE)})
возвращает NULL для всех переменных.
Это проблема tibble vs data frame? Как извлечь эти атрибуты из столбцов таблицы в список?
Обратите внимание, что вектор меток назван, и мне нужны и метки, и имена.
В соответствии с запросом @Hack-R здесь приведен небольшой фрагмент моих данных, преобразованных в dput (который я никогда раньше не использовал). Я применил этот код:
filter(cps_00093.df, YEAR==2015) %>%
sample_n(10) %>%
select(HHTENURE, HHINTYPE) -> tiny
dput(tiny, file = "tiny")
сделать файл крошечным. Привет! Это было просто! Я думал, что будет трудно разорвать такой маленький кусочек.
Открывая крошечный с Notepad++, вот что я нашел:
structure(list(HHTENURE = structure(c(2L, 1L, 1L, 2L, 1L, 1L,
1L, 2L, 1L, 1L), labels = structure(c(0L, 1L, 2L, 3L, 6L, 7L), .Names = c("niu",
"owned or being bought", "rented for cash", "occupied without payment of cash rent",
"refused", "don't know")), class = "labelled"), HHINTYPE = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), labels = structure(1:3, .Names = c("interview",
"type a non-interview", "type b/c non-interview")), class = "labelled")), row.names = c(NA,
-10L), class = c("tbl_df", "tbl", "data.frame"), .Names = c("HHTENURE",
"HHINTYPE"))
Я подозреваю, что это может быть сделано более читабельным с небольшим интервалом, но я не хотел портить его из-за страха случайного уничтожения соответствующей информации.
2 ответа
Я собираюсь попытаться ответить на этот вопрос, хотя мой код не очень хорош.
Сначала я делаю функцию для извлечения именованного атрибута из одного столбца.
ColAttr <- function(x, attrC, ifIsNull) {
# Returns column attribute named in attrC, if present, else isNullC.
atr <- attr(x, attrC, exact = TRUE)
atr <- if (is.null(atr)) {ifIsNull} else {atr}
atr
}
Затем функция, чтобы применить его ко всем столбцам:
AtribLst <- function(df, attrC, isNullC){
# Returns list of values of the col attribute attrC, if present, else isNullC
lapply(df, ColAttr, attrC=attrC, ifIsNull=isNullC)
}
Наконец я запускаю его для каждого атрибута.
stub93 <- AtribLst(cps_00093.df, attrC="label", isNullC=NA)
labels93 <- AtribLst(cps_00093.df, attrC="labels", isNullC=NA)
labels93 <- labels93[!is.na(labels93)]
Все столбцы имеют атрибут "метка", но только некоторые имеют тип "помеченный" и, следовательно, имеют атрибут "метки". Атрибут метки имеет имя, где метки соответствуют значениям данных, а имена сообщают вам, что означают эти значения.
Первоначальный вопрос спрашивает, как "извлечь значения атрибута label в список". Решение основного вопроса следует (при условии some_df
импортируется через haven
и имеет label
атрибуты):
library(purrr)
n <- ncol(some_df)
labels_list <- map(1:n, function(x) attr(some_df[[x]], "label") )
# if a vector of character strings is preferable
labels_vector <- map_chr(1:n, function(x) attr(some_df[[x]], "label") )
Прыгая с @omar-waslow, ответ выше, но добавляя использование attr_getter
.
Если данные (some_df
) импортируется с использованием read_dta
в haven
пакет, то каждый столбец в таблице имеет attr
называется "label"
. Итак, мы разделили фрейм данных по столбцам. Это создает фрейм данных с двумя столбцами, которые можно соединить обратно (например, после pivot_longer).
library(tidyverse)
label_lookup_map <- tibble(
col_name = some_df %>% names(),
labels = some_df %>% map_chr(attr_getter("label"))
)