2016-09-24 68 views
4

應用於Stata文件的Hadley Wickham的haven軟件包返回包含許多「標籤」類型的列的tibble。你可以看到這些通過str(),例如:R:從Stata提供的「標籤」加密列中提取標籤屬性

$ 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與數據框架的問題?我如何從tibble列中將這些屬性提取到列表中?

請注意,標籤向量是命名的,我需要標籤和名稱。

根據@ Hack-R的要求,這裏是我的數據的一小部分,由dput轉換(我以前從未使用過)。我申請了這個代碼:

filter(cps_00093.df, YEAR==2015) %>% 
    sample_n(10) %>% 
    select(HHTENURE, HHINTYPE) -> tiny 
dput(tiny, file = "tiny") 

產生的文件很小。嘿!那很簡單!我認爲這很難打破這一小塊。

打開微小用記事本+ +,這是我發現:

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")) 

我懷疑這可能是由一個小間距的可讀性,但我並不想用它淤泥生怕一不小心破壞有關信息。

+0

莫非你'dput()所需的數據的'的最小量爲封裝所述問題可再現的例子? –

+0

參見'?haven :: labelled';他們有自己的'as_factor'方法。 – alistaire

+0

感謝您的提示,@alistaire!不幸的是,每列的數據部分中的唯一值的數量和標籤矢量的相對長度都在地圖上。對於大多數欄目來說,既不是一對一的比賽,也不是一對缺少的代碼。因此,我沒有準備好相信一刀切的轉換,直到我更仔細地查看數據並找出發生了什麼。 – andrewH

回答

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 
} 

然後一個函數,lapply所有列:

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)] 

所有列有一個「標籤」屬性,但只有一些有型的「標記」,因此有一個「標籤」屬性。 labels屬性是命名的,標籤與數據的值匹配,名稱告訴你這些值是什麼意思。

1

原始問題詢問如何'將標籤屬性的值提取到列表中。'有解決的主要問題如下(假設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"))