переименовать переменные с метками переменных в R
Я всегда работаю с коллегами в SPSS и STata, поэтому четкие метки переменных действительно важны для сообщения того, что было сделано с любой данной переменной и что она записывает.
Как мне наиболее эффективно переименовать переменные с их метками переменных в контексте tidyverse. Я могу это сделать, но это кажется очень громоздким.
var1<-rnorm(100)
var2<-rnorm(100)
var3<-rnorm(100)
group_var<-sample(c("A", "B"), size=100, replace=T)
other_var1<-rnorm(100)
other_var2<-rnorm(100)
df<-data.frame(var1, var2, var3, group_var, other_var1, other_var2)
library(labelled)
library(tidyverse)
df %>%
set_variable_labels(var1="Measure 1",
var2="Measure 2",
var3="Measure 3",
group_var="Grouping Variable")->df
#Store variable labels
df %>%
select(starts_with("var")) %>%
var_label() %>%
unlist()->variable_labels
variable_labels<-data.frame(name=names(variable_labels), labels=variable_labels)
df %>%
pivot_longer(var1:var3) %>%
left_join(., variable_labels, by="name")
Есть ли способ сделатьrename_with
функция здесь работает? Это не так.
df %>%
rename_with(., function(x) var_label(x),.cols=var1:var3)
2 ответа
Мы могли бы использовать!!!
сrename
в именованном списке или векторе, созданном изvariable_labels
набор данных
library(dplyr)
library(tibble)
df <- df %>%
rename(!!! deframe(variable_labels[2:1]))
-Проверьте имена
> names(df)
[1] "Measure 1" "Measure 2" "Measure 3" "group_var" "other_var1" "other_var2"
Или если мы хотим использоватьrename_with
df <- df %>%
rename_with(~ variable_labels$labels,
.cols = variable_labels$name)
Причина не работает, потому что она ищет значение столбцов, а не имена столбцов, т.е. в соответствии с?var_label
x - вектор или data.frame
var_label("var1")
NULL
тогда как
> var_label(df$var1)
[1] "Measure 1"
Если мы копаем функциюrename_with.data.frame
было бы нагляднее
getAnywhere('rename_with.data.frame')
function (.data, .fn, .cols = everything(), ...)
{
.fn <- as_function(.fn)
cols <- tidyselect::eval_select(enquo(.cols), .data)
names <- names(.data)
names[cols] <- .fn(names[cols], ...)
names <- vec_as_names(names, repair = "check_unique")
set_names(.data, names)
}
то есть.fn
или лямбда-функция применяется к именам столбцов. Таким образом, когда мы используемvar_label
, он требует data.frame или вектор, и он терпит неудачу
-добавлены операторы печати в модифицированной функции
rename_with_mod <- function (.data, .fn, .cols = everything(), ...)
{
cols <- tidyselect::eval_select(enquo(.cols), .data)
print("cols")
print(cols)
names <- names(.data)
print("names")
print(names)
.fn <- rlang::as_function(.fn)
print(names[cols])
.fn(names[cols], ...)
}
-Тестирование
# lambda function to return the column name
> df %>%
+ rename_with_mod(~ .x, .cols=var1:var3)
[1] "cols"
var1 var2 var3
1 2 3
[1] "names"
[1] "var1" "var2" "var3" "group_var" "other_var1" "other_var2"
[1] "var1" "var2" "var3"
[1] "var1" "var2" "var3"
# lambda function where we apply the var_label - returns NULL
> df %>%
+ rename_with_mod(~ var_label(.x), .cols=var1:var3)
[1] "cols"
var1 var2 var3
1 2 3
[1] "names"
[1] "var1" "var2" "var3" "group_var" "other_var1" "other_var2"
[1] "var1" "var2" "var3"
NULL
Вы также можете использовать атрибуты напрямую:
colnames(data) <- sapply(data, function(x) attr(x, "label"))
Или, если вы предпочитаетеvar_label
иrename_with
(помните, что здесь нет маскирования данных, поэтомуdata
, нет.data
):
data |>
rename_with(function(x) sapply(x, function(y) var_label(data[[y]])))
Пример с пометкойhaven
iris
данные:
library(haven)
> path <- system.file("examples", "iris.dta", package = "haven")
> data <- read_dta(path)
> data
# A tibble: 150 × 5
sepallength sepalwidth petallength petalwidth species
<dbl> <dbl> <dbl> <dbl> <chr>
1 5.10 3.5 1.40 0.200 setosa
2 4.90 3 1.40 0.200 setosa
3 4.70 3.20 1.30 0.200 setosa
4 4.60 3.10 1.5 0.200 setosa
5 5 3.60 1.40 0.200 setosa
6 5.40 3.90 1.70 0.400 setosa
7 4.60 3.40 1.40 0.300 setosa
8 5 3.40 1.5 0.200 setosa
9 4.40 2.90 1.40 0.200 setosa
10 4.90 3.10 1.5 0.100 setosa
# … with 140 more rows
> colnames(data) <- sapply(data, function(x) attr(x, "label"))
> data
# A tibble: 150 × 5
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<dbl> <dbl> <dbl> <dbl> <chr>
1 5.10 3.5 1.40 0.200 setosa
2 4.90 3 1.40 0.200 setosa
3 4.70 3.20 1.30 0.200 setosa
4 4.60 3.10 1.5 0.200 setosa
5 5 3.60 1.40 0.200 setosa
6 5.40 3.90 1.70 0.400 setosa
7 4.60 3.40 1.40 0.300 setosa
8 5 3.40 1.5 0.200 setosa
9 4.40 2.90 1.40 0.200 setosa
10 4.90 3.10 1.5 0.100 setosa
# … with 140 more rows
Рассмотрите возможность использованияjanitor::make_clean_names
потом облегчить себе жизнь.