web-dev-qa-db-fra.com

R: attribuer des étiquettes variables aux colonnes du bloc de données

J'ai du mal avec les étiquettes variables des colonnes data.frame. Disons que j'ai la trame de données suivante (qui fait partie d'une trame de données beaucoup plus grande):

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

J'ai également un vecteur nommé avec les étiquettes variables pour ce bloc de données:

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

Je veux affecter les étiquettes des variables dans var.labels aux colonnes du bloc de données data à l'aide de la fonction label du package Hmisc. Je peux les faire un par un comme ça et vérifier le résultat par la suite:

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

Les étiquettes de variables sont affectées en tant qu'attributs des colonnes:

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

Magnifique. Cependant, avec une trame de données plus grande, disons 100 colonnes ou plus, cela ne sera ni pratique ni efficace. Une autre option consiste à leur attribuer directement des attributs:

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

N'aide pas. Les étiquettes des variables ne sont pas affectées aux colonnes:

> label(data)
age sex
 ""  ""

Au lieu de cela, ils sont attribués en tant qu'attribut du bloc de données lui-même (voir le dernier composant de la liste):

> 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"

Et ce n'est pas ce que je veux. J'ai besoin des étiquettes variables comme attributs des colonnes. J'ai essayé d'écrire la fonction suivante (et bien d'autres):

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

Et puis exécutez-le:

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

N'a pas aidé. Il renvoie les valeurs du vecteur var.labels mais n'attribue pas les étiquettes de variable. Si j'essaye de l'assigner à un nouvel objet, il contient juste les valeurs des étiquettes variables comme vecteur.

20
panman

Vous pouvez le faire en créant une liste à partir du vecteur nommé de var.labels Et en l'affectant aux valeurs label. J'ai utilisé match pour m'assurer que les valeurs de var.labels Sont affectées à leur colonne correspondante dans data même si l'ordre de var.labels Est différent de l'ordre des colonnes 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" 

Réponse originale

Ma réponse d'origine utilisait lapply, ce qui n'est pas vraiment nécessaire. Voici la réponse originale à des fins d'archivage:

Vous pouvez attribuer les étiquettes à l'aide de lapply:

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

lapply applique une fonction à chaque élément d'une liste ou d'un vecteur. Dans ce cas, la fonction est appliquée à chaque valeur de names(data) et récupère la valeur d'étiquette dans var.labels Qui correspond à la valeur actuelle de names(data).

La lecture de quelques didacticiels est un bon moyen de se faire une idée générale, mais vous y arriverez vraiment si vous commencez à utiliser lapply dans différentes situations et voyez comment cela se comporte.

20
eipi10

Je recommande fortement d'utiliser la fonction Hmisc::upData().

Voici un exemple 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 |
#> +--------+------+
9
avallecam

Si votre vecteur d'étiquettes correspond à l'ordre de vos colonnes data.frame, mais n'est pas un vecteur nommé (il ne peut donc pas être utilisé pour sous-définir les colonnes data.frame par nom comme l'approche lapply dans l'autre réponse ), vous pouvez utiliser une boucle 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"
3
Sam Firke