Динамическое присвоение переменным фрейма данных для добавления меток значений в R, использование коэффициентов, set_labels пакета «sjmisc»

#r #function #automation #labels #factors

#r #функция #автоматизация #label #факторы

Вопрос:

Я хочу присвоить метки значений числовым данным, чтобы метки отображались при составлении таблиц Или создании некоторых диаграмм. Помня об этом, я подумал об использовании факторов, чтобы я мог присваивать метки и при необходимости генерировать некоторую статистику, такую как среднее значение, используя числовые значения в уровнях. В моей базе данных более 150 переменных, и мне нужно присвоить метки значений примерно 120 из этих переменных. Метки от переменной к переменной к значению будут отличаться, могут быть одинаковыми для нескольких переменных.

Чтобы проиллюстрировать проблему и ускорить выполнение, я создал образец данных, как показано ниже —

 Q1 <- sample(1:5,20,replace = T)
Q2 <- sample(1:5,20,replace = T)
Q3 <- sample(1:5,20,replace = T)
Q4 <- sample(1:5,20,replace = T)
Q5 <- sample(1:5,20,replace = T)

df <- as.data.frame(cbind(Q1,Q2,Q3,Q4,Q5))
class(df)
  

У меня есть отдельный фрейм данных, в котором есть значение и метки для каждого вопроса

 mylabel <- data.frame(Q1 = 1:5,Q1_desc = c("Strongly Disagree","Disagree","Neither","Agree","Strongly Agree"),
                  Q2 = 1:5,Q2_desc = c("Strongly Disagree","Disagree","Neither","Agree","Strongly Agree"),
                  Q3 = 1:5,Q3_desc = c("Strongly Disagree","Disagree","Neither","Agree","Strongly Agree"),
                  Q4 = 1:5,Q4_desc = c("Strongly Disagree","Disagree","Neither","Agree","Strongly Agree"),
                  Q5 = 1:5,Q5_desc = c("Strongly Disagree","Disagree","Neither","Agree","Strongly Agree"))
  

Теперь позвольте мне проиллюстрировать код для одной переменной —

 df$Q1 <- factor(df$Q1,
              levels = c(1,2,3,4,5),
              labels = c("Strongly Disagree","Disagree","Neither","Agree","Strongly Agree"))

df$Q1
mean(as.numeric(df$Q1))
barplot(table(df$Q1))
table(df$Q1)
  

Приведенный выше код использует Q1 в качестве фактора и присваивает уровни и метки переменной Q1 в фрейме данных. Я могу сгенерировать среднее значение / гистограмму с метками и таблицу с метками. Поскольку у меня есть много переменных, где необходимо выполнить эту задачу, я подумал о написании функций. И здесь мне нужна помощь!

Ниже приведен код функции —

 getlabels <- function(varname){
  #varname <- "Q1"
  lev <- na.omit(with(mylabel, get(varname)))
  lab <- na.omit(with(mylabel,get(paste0(varname,"_desc"))))
  df$varname <- factor(with(df,get(varname)),
                     levels = lev,
                     labels = lab)
}

getlabels("Q2")
  

Приведенный выше код не выдает никаких ошибок, но не обновляет df ни метками, ни уровнями для Q2. Q2 по-прежнему является числовым столбцом. Похоже, присвоение функции factor не происходит для df$ varname. Может ли кто-нибудь подсказать, почему это могло произойти и как мы можем это преодолеть.

#

Затем я попробовал другой метод, используя пакет «sjmisc», чтобы достичь этого. Я могу достичь этого для одной переменной с помощью приведенного ниже кода —

 df$Q2 <- set_labels(df$Q2,c("Strongly Disagree","Disagree","Neither","Agree","Strongly Agree"))
df$Q2
  

Вышеописанное присваивает метки в качестве атрибута. Теперь, поскольку мне нужно выполнить это для нескольких переменных, я подумал о преобразовании этого в функцию. Опять же, в этом случае также не удается обновить df, поскольку присвоение не происходит.
При использовании функции assign я не получаю никаких ошибок, но атрибуты не обновляются.

 getlabels2 <- function(varname){
  #varname <- "Q1"
  lev <- na.omit(with(mylabel, get(varname)))
  lab <- na.omit(with(mylabel,get(paste0(varname,"_desc"))))
  ##setting lab to named variable as set_labels needs a named variable
  names(lab) <- na.omit(paste("mylabel$","varname"))
  assign(paste("df$",varname),set_labels(with(df,varname),lab))
}

getlabels2("Q2")

df$Q2
  

Поскольку количество переменных больше, я считаю, что решение функции помогло бы автоматизировать эту повторяющуюся задачу. Наконец, я хочу использовать функцию в, возможно, lapply, чтобы мне не приходилось вызывать функцию 120 раз. Было бы полезно, если бы кто-нибудь мог предложить и по этому поводу.

Спасибо!!

Комментарии:

1. set_labels() и другие функции sjmisc также работают с фреймами данных, так что вы можете использовать set_labels(df, ...) .

Ответ №1:

Мне как бы интересно, почему вы просто не пишете for цикл и не двигаетесь дальше:

 for (i in names(df)){
  df[[i]] <- factor(df[[i]],
                    levels = mylabel[[i]],
                    labels = mylabel[[paste0(i,"_desc")]])
}

> str(df)
'data.frame':   20 obs. of  5 variables:
 $ Q1: Factor w/ 5 levels "Strongly Disagree",..: 2 2 4 1 4 2 5 5 1 2 ...
 $ Q2: Factor w/ 5 levels "Strongly Disagree",..: 1 5 3 3 2 3 5 1 4 2 ...
 $ Q3: Factor w/ 5 levels "Strongly Disagree",..: 2 5 2 5 5 2 4 4 5 3 ...
 $ Q4: Factor w/ 5 levels "Strongly Disagree",..: 3 3 2 1 1 3 1 2 1 3 ...
 $ Q5: Factor w/ 5 levels "Strongly Disagree",..: 2 2 1 4 5 4 1 3 1 1 ...
  

В качестве дополнительного примечания, этого лучше избегать as.data.frame(cbind()) ; это плохой шаблон кода и, честно говоря, просто больше ввода, чем вам нужно. df <- data.frame(Q1,Q2,Q3,Q4,Q5) было достаточным и безопасным.

Комментарии:

1. Спасибо, Джоран!! Это сработало и кажется довольно кратким. Отметил вашу точку зрения по созданию фрейма данных. Еще раз спасибо!!