Извлеките атрибут метки из "помеченных" столбцов тиббла из импорта в гавань из 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"))
)
Другие вопросы по тегам