从Stata的避风港导入中"标记"的tibble列中提取标签属性

and*_*ewH 11 attributes r stata data-structures r-haven

Hadley Wickham的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" ...
Run Code Online (Sandbox Code Playgroud)

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

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

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

为所有变量返回NULL.

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

请注意,标签向量已命名,我需要标签和名称.

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

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

生成文件很小.嘿! 那很简单!我觉得很难打破这么小的一块.

使用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"))
Run Code Online (Sandbox Code Playgroud)

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

Oma*_*sow 7

原始问题询问如何"将标签属性的值提取到列表中." 主要问题的解决方案如下(假设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") )
Run Code Online (Sandbox Code Playgroud)


and*_*ewH 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
}
Run Code Online (Sandbox Code Playgroud)

然后是一个将其应用于所有列的函数:

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)
}
Run Code Online (Sandbox Code Playgroud)

最后我对每个属性运行它。

stub93 <- AtribLst(cps_00093.df, attrC="label", isNullC=NA)

labels93 <- AtribLst(cps_00093.df, attrC="labels", isNullC=NA)
labels93 <- labels93[!is.na(labels93)]
Run Code Online (Sandbox Code Playgroud)

所有列都具有“标签”属性,但只有某些列的类型为“标签”,因此具有“标签”属性。标签属性被命名,其中标签与数据值匹配,并且名称告诉您这些值的含义。