从"标记为"提取标签属性来自Stata的避风港的Tibble柱子

时间:2016-09-24 01:25:01

标签: r data-structures attributes stata r-haven

Hadley Wickham的$ 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" ... 包应用于Stata文件,返回一个包含许多类型"标记为"的列的tibble。您可以使用str()来查看这些内容,例如:

labels93 <- lapply(cps_00093.df, function(x){attr(X, which="labels", exact=TRUE)})

如果我可以简单地将所有这些标记的向量提取到因子,那将是很好的,但我已经将标签属性的长度与每个向量中的唯一值的数量进行了比较,并且有时更长,有时更短。所以我认为我需要查看所有这些并决定如何单独处理每一个。

所以我想将labels属性的值提取到列表中。但是,这个功能:

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

为所有变量返回NULL。

这是一个tibble vs数据帧问题吗?如何从tibble列中将这些属性提取到列表中?

请注意,标签矢量已命名,我需要标签和名称。

根据@ Hack-R的请求,这里是我的数据的一小部分,由dput转换(我以前从未使用过)。我应用了这段代码:

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

生成文件很小。嘿!那很简单!我认为很难打破这么小的一块。

用Notepad ++打开微小,这就是我发现的:

getRandomEntry()

我怀疑这可以通过一点间距变得更具可读性,但我不想因为害怕意外破坏相关信息而捣乱。

3 个答案:

答案 0 :(得分:7)

原始问题询问如何将标签属性的值提取到列表中。&#39;主要问题的解决方案如下(假设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") )

答案 1 :(得分: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”属性,但只有一些属于“已标记”类型,因此具有“标签”属性。将命名labels属性,其中标签与数据的值匹配,名称将告诉您这些值表示的含义。

答案 2 :(得分:0)

跳过上述@ omar-waslow答案,但增加了对attr_getter的使用。

如果使用some_df包中的read_dta导入了数据(haven,则该小标题中的每一列都有一个名为attr的{​​{1}}。因此,我们将数据帧拆分,逐列进行。这样会创建一个两列数据框,可以将其联接回去(例如,在pivot_longer之后)。

"label"