【问题标题】:R: Assign variable labels of data frame columnsR:分配数据框列的变量标签
【发布时间】:2015-02-05 11:48:23
【问题描述】:

我正在努力处理 data.frame 列的可变标签。假设我有以下数据框(更大数据框的一部分):

data <- data.frame(age = c(21, 30, 25, 41, 29, 33), sex = factor(c(1, 2, 1, 2, 1, 2), labels = c("Female", "Male")))
#

我还有一个命名向量,其中包含此数据框的变量标签:

var.labels <- c(age = "Age in Years", sex = "Sex of the participant")

我想使用Hmisc 包中的函数labelvar.labels 中的变量标签分配给数据框data 中的列。我可以像这样一个一个地做,然后检查结果:

> label(data[["age"]]) <- "Age in years"
> label(data[["sex"]]) <- "Sex of the participant"
> label(data)
                 age                      sex
      "Age in years" "Sex of the participant"

变量标签被分配为列的属性:

> attr(data[["age"]], "label")
[1] "Age in years"
> attr(data[["sex"]], "label")
[1] "Sex of the participant"

太棒了。但是,对于较大的数据框,例如 100 列或更多列,这将不方便或高效。另一种选择是直接将它们分配为属性:

> attr(data, "variable.labels") <- var.labels

没有帮助。变量标签未分配给列:

> label(data)
age sex
 ""  ""

相反,它们被分配为数据框本身的属性(请参阅列表的最后一个组件):

> attributes(data)
$names
[1] "age" "sex"

$row.names
[1] 1 2 3 4 5 6

$class
[1] "data.frame"

$variable.labels
                 age                      sex
      "Age in Years" "Sex of the participant"

这不是我想要的。我需要变量标签作为列的属性。我尝试编写以下函数(以及许多其他函数):

set.var.labels <- function(dataframe, label.vector){
  column.names <- names(dataframe)
  dataframe <- mapply(label, column.names, label.vector)
  return(dataframe)
}

然后执行:

> set.var.labels(data, var.labels)

没有帮助。它返回向量var.labels 的值,但不分配变量标签。如果我尝试将它分配给一个新对象,它只包含变量标签的值作为向量。

【问题讨论】:

    标签: r dataframe labels assign hmisc


    【解决方案1】:

    您可以通过从var.labels 的命名向量创建一个列表并将其分配给label 值来实现此目的。我使用match 来确保var.labels 的值被分配给data 中的相应列,即使var.labels 的顺序与data 列的顺序不同。

    library(Hmisc)
    
    var.labels = c(age="Age in Years", sex="Sex of the participant")
    
    label(data) = as.list(var.labels[match(names(data), names(var.labels))])
    
    label(data)
                         age                      sex 
              "Age in Years" "Sex of the participant" 
    

    原答案

    我的原始答案使用了lapply,实际上没有必要。以下是存档目的的原始答案:

    您可以使用lapply 分配标签:

    label(data) = lapply(names(data), function(x) var.labels[match(x, names(var.labels))])
    

    lapply 将函数应用于列表或向量的每个元素。在这种情况下,该函数应用于names(data) 的每个值,并从var.labels 中挑选出与names(data) 的当前值相对应的标签值。

    阅读一些教程是了解总体思路的好方法,但如果您开始在不同情况下使用lapply 并查看其行为方式,您将真正掌握它的窍门。

    【讨论】:

    • @eipi10:非常感谢!有用!这正是我所需要的。在使用 apply 系列函数时,我无法理解索引。有没有我可以阅读的指南或者这是经验问题?
    • 有关lapplythisthis 的简短教程可能会有所帮助。我还为我的答案添加了更多解释。
    • 谢谢!我不明白的是为什么在你做了lapply(names(var.labels), function(x) label(data[,x]) = var.labels[x])之后,标签分配已经在哪里了,还得做label(data) =
    • 你是对的。没有必要做任务。感谢您指出了这一点。我已经修复了代码并更新了代码,以便它分配正确的标签,而不管var.labels 的顺序如何,也不管names(var.labels) 是否包含names(data) 中不存在的其他元素。
    • 实际上,几年后回到这个,我发现lapply 甚至没有必要。我已经相应地更新了答案。但是,@avallecam 使用Hmisc 函数upData 的答案是更新标签的更方便的方法。
    【解决方案2】:

    我强烈推荐使用Hmisc::upData() 函数。

    这里是reprex 示例:


    set.seed(22)
    data <- data.frame(age = floor(rnorm(6,25,10)), 
                       sex = gl(2,1,6, labels = c("f","m")))
    var.labels <- c(age = "Age in Years", 
                    sex = "Sex of the participant")
    dplyr::as.tbl(data) # as tibble ---------------------------------------------
    #> # A tibble: 6 × 2
    #>     age    sex
    #>   <dbl> <fctr>
    #> 1    19      f
    #> 2    49      m
    #> 3    35      f
    #> 4    27      m
    #> 5    22      f
    #> 6    43      m
    data <- Hmisc::upData(data, labels = var.labels) # update data --------------
    #> Input object size:    1328 bytes;     2 variables     6 observations
    #> New object size: 2096 bytes; 2 variables 6 observations
    Hmisc::label(data) # check new labels ---------------------------------------
    #>                      age                      sex 
    #>           "Age in Years" "Sex of the participant"
    Hmisc::contents(data) # data dictionary -------------------------------------
    #> 
    #> Data frame:data  6 observations and 2 variables    Maximum # NAs:0
    #> 
    #> 
    #>                     Labels Levels   Class Storage
    #> age           Age in Years        integer integer
    #> sex Sex of the participant      2         integer
    #> 
    #> +--------+------+
    #> |Variable|Levels|
    #> +--------+------+
    #> |   sex  |  f,m |
    #> +--------+------+
    

    【讨论】:

    • Hmisc::upData(data, labels = ) 太棒了!搜索这个几个小时。
    • 如果要将变量标签导出为 .dta (stata) 格式,Hmisc::upData() 会显示此issue。而是使用labelled::set_variable_labels(),例如:cars %&gt;% labelled::set_variable_labels(speed = "speed in mph", dist = "stopping distance in ft") %&gt;% haven::write_dta("cars.dta")
    【解决方案3】:

    你可以使用包{labelled}代替{Hmisc}

    data <- labelled::set_variable_labels(data, .labels = var.labels)
    

    【讨论】:

    • 可能是个愚蠢的问题,但 R-script 不支持开箱即用的变量标签?我的意思是,您总是需要一个带有添加或更改标签功能的附加包?
    • 你可以使用基本的R函数attr()。请参阅最上面的问题帖子。依赖包是因为分配属性不是很方便。问题在于,base R 这样做的方式是非常一般的方式,而不是专门针对仅标记变量或值的任务的方式。
    【解决方案4】:

    如果您的标签向量与 data.frame 列的顺序匹配,但不是命名向量(因此不能用于按名称对 data.frame 列进行子集化,如另一个答案中的 lapply 方法),您可以使用 for 循环:

    for(i in seq_along(data)){
      Hmisc::label(data[, i]) <- var.labels[i]
    }
    
    label(data)
    #>                      age                      sex 
    #>           "Age in Years" "Sex of the participant"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-17
      • 2012-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多