首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从来自Stata的haven导入的“labels”tibble列中提取labels属性

从来自Stata的haven导入的“labels”tibble列中提取labels属性
EN

Stack Overflow用户
提问于 2016-09-24 09:25:01
回答 3查看 7.6K关注 0票数 17

Hadley Wickham的haven包应用于Stata文件,返回一个带有许多“标签”类型的列的tibble。您可以使用str()查看这些内容,例如:

代码语言:javascript
复制
$ 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" ...

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

所以我想把labels属性的值提取到一个列表中。但是,此函数:

代码语言:javascript
复制
labels93 <- lapply(cps_00093.df, function(x){attr(X, which="labels", exact=TRUE)})

为所有变量返回NULL。

这是tibble vs data frame的问题吗?如何将这些属性从tibble列提取到列表中?

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

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

代码语言:javascript
复制
filter(cps_00093.df, YEAR==2015) %>%
  sample_n(10)  %>%
  select(HHTENURE, HHINTYPE) -> tiny
dput(tiny, file = "tiny")

来生成文件tiny。嘿!这很简单!我以为这么小的一块很难折断。

用Notepad++打开tiny,这是我发现的:

代码语言:javascript
复制
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"))

我猜想用一点空格就可以使这篇文章更具可读性,但我不想把它弄得乱七八糟,以免意外地破坏相关的信息。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-09-25 04:13:48

我将尝试回答这个问题,尽管我的代码不是很漂亮。

首先,我创建了一个函数来从单个列中提取一个命名属性。

代码语言:javascript
复制
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
}

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

代码语言:javascript
复制
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)
}

最后,我为每个属性运行它。

代码语言:javascript
复制
stub93 <- AtribLst(cps_00093.df, attrC="label", isNullC=NA)

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

所有列都有一个"label“属性,但只有一些列的类型是”label“,因此有一个"labels”属性。labels属性被命名,其中标签与数据的值匹配,名称告诉您这些值的含义。

票数 2
EN

Stack Overflow用户

发布于 2017-11-20 00:42:50

最初的问题是如何“将labels属性的值提取到列表中”。主要问题的解决方案如下(假设some_df是通过haven导入的,并且具有label属性)。更新:我现在添加了一种使用sjlabelled包提取标签向量的方法。

代码语言:javascript
复制
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") )

# to make a simple codebook
library(kable)
variable_name <- names(some_df)
data.frame(variable_name, description = labels_vector) %>%
  kable(format = 'markdown')

# UPDATE: another approach with package sjlabelled
library(sjlabelled)
sjlabelled::get_label(some_df)
票数 11
EN

Stack Overflow用户

发布于 2020-07-28 05:49:26

跳过上面的@omar-waslow回答,但添加了attr_getter的使用。

如果数据(some_df)是使用haven包中的read_dta导入的,那么haven中的每一列都有一个名为attr"label"。所以我们拆分数据帧,一列接着一列。这将创建一个两列的数据帧,该数据帧可以连接回来(例如,在pivot_longer之后)。

代码语言:javascript
复制
library(tidyverse)
label_lookup_map <- tibble(
   col_name = some_df %>% names(),
   labels = some_df %>% map_chr(attr_getter("label"))
)
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39671621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档