为tbl_summary准备数据:转换为数字而不丢失标签属性

问题描述

我阅读了CSV调查,其中包含500多个变量(以字符为单位)。我使用library(labelled)为大多数这些变量分配了变量标签和值标签。然后将结果传递到tbl_summary。

请参阅此处: https://raw.githubusercontent.com/larmarange/labelled/master/cheatsheet/labelled_cheatsheet.pdf

为了分配变量标签和值,我首先通过传递每个变量的列表来标记所有变量。接下来,我使用“ set_value_labels”为大多数变量添加了值标签。为了给变量添加标签,我必须确保每个变量都是一个字符。

问题:标记完所有感兴趣的变量和值后,如果不删除标签,我似乎无法转换为数字。

这是我尝试的一个温和的例子。

以字符串形式读取CSV文件

mtcars2 <- mtcars %>% mutate_if(is.numeric,as.character)

为一些变量分配标签

var_label(mtcars2) <- list(mpg = "Miles Per gallon",cyl = "Cylinder",disp = "displacement")

将值标签分配给某些变量:为了使它起作用,所有变量都必须是字符(因此为什么我在CSV中将字符串读取为字符)。如果没有,我得到错误Error: Can't convert `labels` <character> to match type of `x` <double>.

mtcars3 <- mtcars2 %>% set_value_labels(cyl=c(`4`="four",`6`=six,`8`="eight")) %>% haven::as_factor(.)

have :: factors(。)应该保留标签,但不能保留(也许是因为我使用了不同的包装进行了标签?也许因为这些不是STATA标签,而是手动编码的标签?)

mtcars4 <- mtcars3 %>% mutate(mpg = as.numeric(mpg))

在mtcars3(所有字符串)上运行tbl_summary,这会保留所有标签及其值(非常棒!),但不会提供我认为是数字的变量的平均值。

 tbl_summary(mtcars3)
    

我将一个变量转换为数字,以便可以看到平均值,而不是分类值。但是现在,标签不再包含我转换为数字的每个变量了。

tbl_summary(mtcars4)

如何在不删除标签属性的情况下将mtcars3的某些变量转换为数字?

在应用Haven :: as.factor(。)之前,实际数据的类

> class(survey_clean2$Q51_5)
[1] "haven_labelled" "vctrs_vctr"     "character"

应用了Haven :: factor(。)后的数据类别

class(survey_clean2$Q51_5)
[1] "factor"

以下是一些数据的更好示例

data_in <- read_table2("Q50_2     Q50_3  Q85 Q56
1    <NA>      <NA> <NA>
2    <NA>      <NA> <NA>
3    <NA>      <NA> <NA>
<NA>  Rarely Sometimes   12
5    <NA>      <NA> <NA>
6    <NA>      <NA> <NA>
7    <NA>      <NA> <NA>
8    <NA>      <NA> <NA>
9    <NA>      <NA> <NA>
10  Often Sometimes  65")

我们必须将其全部转换为字符,因为这是我处理后的数据的实际格式。

data_in <- data_nonlab %>% mutate_all(as.character)
str(data_nonlab)

这不适用于数字变量。

tbl_summary(data_in)

所以我将其转换为数字。

data_in_num <- 
data_nonlab %>% mutate(Q50_2 = labelled::labelled(as.numeric(Q50_2),label = attr(Q50_2,"label")))

str(data_in_num)

但是从tbl_summary输出中省略了该var,因为:

tbl_summary(data_in_num)
Column(s) ‘Q50_2’ omitted from output.
Accepted classes are ‘character’,‘factor’,‘numeric’,‘logical’,‘integer’,or ‘difftime’.

解决方法

带有标签的软件包中有一个很棒的功能,可以在以下情况下提供帮助:copy_labels_from() https://larmarange.github.io/labelled/reference/copy_labels.html

在操作剥离标签后,可以使用它重新应用标签。参见下面的示例。

library(gtsummary)
library(tidyverse)

# any operation that results in a loss of labels
trial2 <-
  trial %>%
  select(age,marker) %>%
  purrr::map_dfc(as.numeric)

trial2 %>%
  # copy the labels from the original data frame
  labelled::copy_labels_from(trial) %>%
  tbl_summary()

enter image description here

这是基本的R解决方案:

library(tidyverse)
library(gtsummary)

mtcars %>% 
  mutate(
    cyl = factor(cyl,levels = c(4,6,8),labels = c("four","six","eight"))
  ) %>%
  labelled::set_variable_labels(mpg = "Miles Per Gallon",cyl = "Cylinder",disp = "Displacement") %>%
  select(mpg,cyl,disp) %>%
  tbl_summary()

enter image description here