R中变量标签管理

发布时间:2023-04-23 阅读 918

Stata连享会   主页 || 视频 || 推文 || 知乎 || Bilibili 站

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc, ihelp, rdbalance, gitee, installpkg

课程详情 https://gitee.com/lianxh/Course

课程主页 https://gitee.com/lianxh/Course

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者:陈卓然 (中山大学)
邮箱chenzhr25@mail2.sysu.edu.cn


目录


1. 引言

变量标签是一个变量的详细名字,尽管 R 中可以将变量的名字取得非常长,甚至名字中可以包含空格和标点,但是短小的名字更容易进行编程。此时一个能够对变量进行一个非常漂亮而且详尽的描述的变量标签便显得极为重要了。通过这样的变量标签,我们可以非常容易地记住一个变量的名字指代的是什么。

值标签和变量标签类似。但是值标签指的是对一个变量可能的取值进行的详尽描述,将一个类别变量的取值进行标记的好处在于我们不再需要记忆诸如 1=Extremely poor 或者 7=Excellent 之类的含义了,因而我们可以很容易地通过 info 得到数据集的描述性分析和变量的描述性统计。

一般而言,将数值型数据和 R 中的标签关联起来的是因子变量,然而因子变量只能允许整数映射到一个文字标签当中,而这些整数必须是以 1 开始的,同时每一个值都必须有一个标签。同样,我们不能对因子变量计算均值或者其他的统计量。

通过标签我们能够在编程的时候使用短小的变量名字,而在结果输出的表格中我们能够看到文字版本的标签,这样对于结果的可视性有着非常大的帮助。

尽管在 R 中将标签作为变量的属性进行存储是一件非常方便的事情,但是绝大多数的 R 包并不能使用这些标签,甚至是删除这些标签。本文将要介绍的两个包:第一个包是 expss,它能够将值标签整合到 R 中的基础函数和其他包中的函数中,其中的函数 use_labels 能够很大程度上简化变量标签的使用;第二个包是 labelled

2. expss 包

2.1 设置变量和值标签

首先我们可以将变量的标签添加到一个数据集中,如:

library(expss)
data(mtcars)
mtcars = apply_labels(mtcars,
    mpg = "Miles/(US) gallon",
    cyl = "Number of cylinders",
    disp = "Displacement (cu.in.)",
    hp = "Gross horsepower",
    drat = "Rear axle ratio",
    wt = "Weight (1000 lbs)",
    qsec = "1/4 mile time",
    vs = "Engine",
    vs = c("V-engine" = 0,
           "Straight engine" = 1),
    am = "Transmission",
    am = c("Automatic" = 0,
          "Manual"=1),
    gear = "Number of forward gears",
    carb = "Number of carburetors"
)

除了 apply_labels 命令,我们还可以使用 var_labval_lab 的函数:

nps = c(-1, 0, 1, 1, 0, 1, 1, -1)
var_lab(nps) = "Net promoter score"
val_lab(nps) = num_lab("
   -1 Detractors
    0 Neutralists    
    1 Promoters    
")

我们也可以读取、添加和移除现存的标签:

var_lab(nps) # get variable label
val_lab(nps) # get value labels
# add new labels
add_val_lab(nps) = num_lab("
    98 Other    
    99 Hard to say
")

# remove label by value
# %d% - diff, %n_d% - names diff 
val_lab(nps) = val_lab(nps) %d% 98
# or, remove value by name
val_lab(nps) = val_lab(nps) %n_d% "Other"

除此之外,也有很多很有用的函数可以直接作用于整个数据集,比如:

> drop_val_labs(nps)
LABEL: Net promoter score 
VALUES:
-1, 0, 1, 1, 0, 1, 1, -1
> drop_var_labs(nps)
VALUES:
-1, 0, 1, 1, 0, 1, 1, -1
VALUE LABELS:               
 -1 Detractors 
  0 Neutralists
  1 Promoters  
 99 Hard to say
> unlab(nps)
[1] -1  0  1  1  0  1  1 -1
> drop_unused_labels(nps)
LABEL: Net promoter score 
VALUES:
-1, 0, 1, 1, 0, 1, 1, -1
VALUE LABELS:               
 -1 Detractors 
  0 Neutralists
  1 Promoters 

2.2 基础 R 和 ggplot2 中的函数使用标签

R 中的基础函数 table 中使用标签:

with(mtcars, table(am, vs))

绘制柱状图:

with(mtcars, 
    barplot(
        table(am, vs), 
        beside = TRUE, 
        legend = TRUE)
)

对于处理数据框类型的函数而言,我们可以使用 use_labels 这一函数:

> use_labels(mtcars, table(am, vs))
            Engine
Transmission V-engine Straight engine
   Automatic       12               7
   Manual           6               7
> use_labels(mtcars, lm(mpg ~ wt + hp + qsec)) %>% summary

Call:
lm(formula = `Miles/(US) gallon` ~ `Weight (1000 lbs)` 
   + `Gross horsepower` + `1/4 mile time`)
Residuals:
LABEL: Miles/(US) gallon 
VALUES:
-3.8591, -1.6418, -0.4636, 1.194, 5.6092
Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         27.61053    8.41993   3.279  0.00278 ** 
`Weight (1000 lbs)` -4.35880    0.75270  -5.791 3.22e-06 ***
`Gross horsepower`  -0.01782    0.01498  -1.190  0.24418    
`1/4 mile time`      0.51083    0.43922   1.163  0.25463    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2.578 on 28 degrees of freedom
Multiple R-squared:  0.8348,	Adjusted R-squared:  0.8171 
F-statistic: 47.15 on 3 and 28 DF,  p-value: 4.506e-11
# boxplot with variable labels
use_labels(mtcars, boxplot(mpg ~ am))

最后我们可以在 ggplot2 中绘制带有变量标签和值标签的图,但是注意在使用之前我们需要使用 facet_grid 公式将标签变量转变为因子变量:

library(ggplot2, warn.conflicts = FALSE)

use_labels(mtcars, {
# '..data' is shortcut for all 'mtcars' data.frame inside expression 
    ggplot(..data) +
        geom_point(aes(y = mpg, x = wt, color = qsec)) +
        facet_grid(factor(am) ~ factor(vs))
}) 

3. Labelled 包

labelled 包中,我们可以通过 var_label() 来指定一个变量的标签:

library(labelled)
var_label(iris$Sepal.Length) <- "Length of sepal"

我们也可以通过使用一个名字列表给一个数据库中的多个变量添加标签,如:

var_label(iris) <- list(Petal.Length = "Length of petal", Petal.Width = "Width of Petal")

为得到变量标签,我们只需使用 var_label

var_label(iris$Petal.Width)

或者

var_label(iris)

为了移除一个变量的标签,我们可以使用 NULL

var_label(iris$Sepal.Length) <- NULL

你可以通过 look_for() 的命令来展示和搜寻变量名和标签,比如:

> look_for(iris)
 pos variable     label           col_type values    
 1   Sepal.Length —               dbl                
 2   Sepal.Width  —               dbl                
 3   Petal.Length Length of petal dbl                
 4   Petal.Width  Width of Petal  dbl                
 5   Species      —               fct   setosa    
                                        versicolor
                                        virginica 
> look_for(iris,'pet')
 pos variable     label           col_type values
 3   Petal.Length Length of petal dbl            
 4   Petal.Width  Width of Petal  dbl  
> look_for(iris, details = FALSE)
 pos variable     label          
 1   Sepal.Length —              
 2   Sepal.Width  —              
 3   Petal.Length Length of petal
 4   Petal.Width  Width of Petal 
 5   Species      —  

3.1 值标签

第一种创建标签向量的方式是使用 labelled() 函数,这一函数的优势在于你不必为向量中的每一个值都赋予一个标签,同时你也可以为那些没有被观测到的值提供标签。比如:

> v <- labelled(c(1,2,2,2,3,9,1,3,2,NA), c(yes = 1, no = 3, "don't know" = 8, refused = 9))
> v
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value      label
     1        yes
     3         no
     8 don't know
     9    refused

通过使用 var_labels() 来得到所有的值标签,使用 val_label() 来得到特定值的值标签:

> val_labels(v)
       yes         no don't know    refused 
         1          3          8          9 
> val_label(v,8)
[1] "don't know"

val_labels() 也可以用来修正一个变量的所有的值标签,而相比之下 val_label() 只能更新某一个特定的值标签,例如:

> val_labels(v) <- c(yes = 1, nno = 3, bug = 5)
> v
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value label
     1   yes
     3   nno
     5   bug
> val_label(v, 3) <- "no"
> v
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value label
     1   yes
     3    no
     5   bug

通过使用 val_label() 你也可以添加或者移除某一特定的值标签。

> val_label(v, 2) <- "maybe"
> val_label(v, 5) <- NULL
> v
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value label
     1   yes
     3    no
     2 maybe

我们也可以将 val_labels() 应用于一个数据框中的一些列。

> df <- data.frame(v1 = 1:3, v2 = c(2, 3, 1), v3 = 3:1)
> val_label(df, 1) <- "yes"
> val_label(df[, c("v1", "v3")], 2) <- "maybe"
> val_label(df[, c("v2", "v3")], 3) <- "no"
> val_labels(df)
$v1
  yes maybe 
    1     2 

$v2
yes  no 
  1   3 

$v3
  yes maybe    no 
    1     2     3 
> val_labels(df[, c("v1", "v3")]) <- c(YES = 1, MAYBE = 2, NO = 3)
> val_labels(df)
$v1
  YES MAYBE    NO 
    1     2     3 

$v2
yes  no 
  1   3 

$v3
  YES MAYBE    NO 
    1     2     3 
> val_labels(df) <- list(v1 = c(yes = 1, no = 3), v2 = c(a = 1, b = 2, c = 3))
> val_labels(df)
$v1
yes  no 
  1   3 

$v2
a b c 
1 2 3 

$v3
  YES MAYBE    NO 
    1     2     3 

3.2 对值标签进行排序

值标签默认是按照他们被创建的顺序进行排列的。

> v <- c(1,2,2,2,3,9,1,3,2,NA)
> val_label(v, 1) <- "yes"
> val_label(v, 3) <- "no"
> val_label(v, 9) <- "refused"
> val_label(v, 2) <- "maybe"
> val_label(v, 8) <- "don't know"
> v
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value      label
     1        yes
     3         no
     9    refused
     2      maybe
     8 don't know

但是有时或许需要对其进行重新的排序,比如说:

> sort_val_labels(v)
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value      label
     1        yes
     2      maybe
     3         no
     8 don't know
     9    refused
> sort_val_labels(v)
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value      label
     1        yes
     2      maybe
     3         no
     8 don't know
     9    refused

> sort_val_labels(v, decreasing = TRUE)
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value      label
     9    refused
     8 don't know
     3         no
     2      maybe
     1        yes
> sort_val_labels(v, according_to = "l")
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value      label
     8 don't know
     2      maybe
     3         no
     9    refused
     1        yes

3.3 将其他值转化为 NA

在一些情况下,没有对应的值标签的值可能会被视为缺失值,为此我们需要将其转为 NA

> v <- labelled(c(1,2,2,2,3,9,1,3,2,NA), c(yes = 1, maybe = 2, no = 3))
> v
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value label
     1   yes
     2 maybe
     3    no
> nolabel_to_na(v)
<labelled<double>[10]>
 [1]  1  2  2  2  3 NA  1  3  2 NA

Labels:
 value label
     1   yes
     2 maybe
     3    no

有时也有可能一个值标签对应一个缺失值,我们可以根据这个值标签挑出缺失值:

> size <- labelled(c(1.88, 1.62, 1.78, 99, 1.91), c("not measured" = 99))
> size
<labelled<double>[5]>
[1]  1.88  1.62  1.78 99.00  1.91

Labels:
 value        label
    99 not measured

> val_labels_to_na(size)
[1] 1.88 1.62 1.78   NA 1.91

3.4 转化为一个因子变量

一个带有标签的向量可以被转化为一个因子变量,通过使用 to_factor(),例如:

> v <- labelled(c(1,2,2,2,3,9,1,3,2,NA), c(yes = 1, no = 3, 
                "don't know" = 8, refused = 9))
> v
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value      label
     1        yes
     3         no
     8 don't know
     9    refused
> to_factor(v)
 [1] yes 2  2  2  no  refused yes  no  2  <NA>   
Levels: yes 2 no don't know refused

我们可以通过 levels 这一个参数来指明什么应该被作为因子水平,默认情况下是将标签 labels 作为因子水平,也可以将值作为因子水平或者是以值为前缀的标签作为因子水平,如:

> to_factor(v)
 [1] yes  2  2  2  no  refused yes  no  2  <NA>   
Levels: yes 2 no don't know refused
> to_factor(v)
 [1] yes  2  2  2  no  refused yes  no  2  <NA>   
Levels: yes 2 no don't know refused
> to_factor(v, levels = "v")
 [1] 1  2  2  2  3  9  1  3  2  <NA>
Levels: 1 2 3 8 9
> to_factor(v,levels = "p")
 [1] [1] yes  [2] 2  [2] 2  [2] 2  [3] no  [9] refused [1] yes  [3] no     
 [9] [2] 2  <NA>       
Levels: [1] yes [2] 2 [3] no [8] don't know [9] refused

此外我们也可以加入参数 ordered 来创建一个有序因子变量:

> to_factor(v, ordered = TRUE)
 [1] yes  2  2  2  no  refused yes  no  2  <NA>   
Levels: yes < 2 < no < don't know < refused

我们也可以加入参数 nolabel_to_na 来指明是否在转为因子变量之前是否需要应用一个函数。因此如下的两条命令是等价的:

> to_factor(nolabel_to_na(v))
 [1] yes     <NA>    <NA>    <NA>    no      refused yes     no      <NA>    <NA>   
Levels: yes no don't know refused
> to_factor(v,nolabel_to_na = TRUE)
 [1] yes     <NA>    <NA>    <NA>    no      refused yes     no      <NA>    <NA>   
Levels: yes no don't know refused

另外一个非常有用的参数是 sorted_levels ,这一参数可以用来指明因子水平应该以何种方式进行排序:其中 none 表示按照值的大小进行排序,labels 表示按照标签排序

> to_factor(v, sort_levels = "n")
 [1] yes  2  2  2  no  refused yes  no  2  <NA>   
Levels: yes no don't know refused 2
> to_factor(v, sort_levels = "l")
 [1] yes  2  2  2  no  refused yes  no  2  <NA>   
Levels: 2 don't know no refused yes

我们也可以使用函数 to_labelled() 来将一个因子变量转化为一个带有标签的数值向量。

> f <- factor(1:3, labels = c("a", "b", "c"))
> f
[1] a b c
Levels: a b c
> to_labelled(f)
<labelled<double>[3]>
[1] 1 2 3

Labels:
 value label
     1     a
     2     b
     3     c

但是需要注意的是,to_labelled(to_factor(v)) 并不等价于 v

> v
<labelled<double>[10]>
 [1]  1  2  2  2  3  9  1  3  2 NA

Labels:
 value      label
     1        yes
     3         no
     8 don't know
     9    refused
> to_labelled(to_factor(v))
<labelled<double>[10]>
 [1]  1  2  2  2  3  5  1  3  2 NA

Labels:
 value      label
     1        yes
     2          2
     3         no
     4 don't know
     5    refused

3.5 有条件地转化为因子变量

为了便于分析,研究者有时需要识别那些带有标签的数值变量是类别型变量 (因此需要使用 to_factor() 将其转化为因子),或者是连续变量 (因子需要对其使用 base::unclass())。需要注意的是绝大多数函数 (包括绝大多数的回归函数和绘图函数如 ggplot2 都需要将类别变量设置为因子变量),为此你需要使用 unlabelled() 来完成这一转变。

> df <- data.frame(
+   a = labelled(c(1, 1, 2, 3), labels = c(No = 1, Yes = 2)),
+   b = labelled(c(1, 1, 2, 3), labels = c(No = 1, Yes = 2, DK = 3)),
+   c = labelled(c(1, 1, 2, 2), labels = c(No = 1, Yes = 2, DK = 3)),
+   d = labelled(c("a", "a", "b", "c"), labels = c(No = "a", Yes = "b")),
+   e = labelled_spss(
+     c(1, 9, 1, 2), 
+     labels = c(No = 1, Yes = 2),
+     na_values = 9
+   )
+ )
> df %>% look_for()
 pos variable label col_type values 
 1   a        —     dbl+lbl  [1] No 
                             [2] Yes
 2   b        —     dbl+lbl  [1] No 
                             [2] Yes
                             [3] DK 
 3   c        —     dbl+lbl  [1] No 
                             [2] Yes
                             [3] DK 
 4   d        —     chr+lbl  [a] No 
                             [b] Yes
 5   e        —     dbl+lbl  [1] No 
                             [2] Yes
> unlabelled(df)%>% look_for()
 pos variable label col_type values
 1   a        —     dbl            
 2   b        —     fct      No    
                             Yes   
                             DK    
 3   c        —     fct      No    
                             Yes   
                             DK    
 4   d        —     chr            
 5   e        —     fct      No    
                             Yes 

4. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh r语言, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,700+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

New! lianxhsongbl 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh