查看原文
其他

R中变量标签管理

连享会 连享会 2023-10-24

👇 连享会 · 推文导航 | www.lianxh.cn

连享会课程 · 2023 五一论文班

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

温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:


目录

  • 1. 引言

  • 2. expss 包

    • 2.1 设置变量和值标签

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

  • 3. Labelled 包

    • 3.1 值标签

    • 3.2 对值标签进行排序

    • 3.3 将其他值转化为 NA

    • 3.4 转化为一个因子变量

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

  • 4. 相关推文



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(-1011011, -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:
-1011011, -1
> drop_var_labs(nps)
VALUES:
-1011011, -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:
-1011011, -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.46361.1945.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(231), 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.881.621.78991.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)
[11.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")
 [11  2  2  2  3  9  1  3  2  <NA>
Levels: 1 2 3 8 9
> to_factor(v,levels = "p")
 [1] [1] yes  [22  [22  [22  [3] no  [9] refused [1] yes  [3] no     
 [9] [22  <NA>       
Levels: [1] yes [22 [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]>
[11 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(1123), labels = c(No = 1, Yes = 2)),
+   b = labelled(c(1123), labels = c(No = 1, Yes = 2, DK = 3)),
+   c = labelled(c(1122), 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(1912), 
+     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

  • 专题:Stata命令
    • Stata与R语言等价命令
  • 专题:倍分法DID
    • 如何在R语言中实现多期DID
  • 专题:Python-R-Matlab
    • R语言随机指数图分析-statnet
    • R语言绘制社会网络图

New! Stata 搜索神器:lianxhsongbl  GIF 动图介绍
搜: 推文、数据分享、期刊论文、重现代码 ……
👉 安装:
. ssc install lianxh
. ssc install songbl
👉  使用:
. lianxh DID 倍分法
. songbl all

🍏 关于我们

  • 连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 直通车: 👉【百度一下: 连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存