#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. Спасибо, Джоран!! Это сработало и кажется довольно кратким. Отметил вашу точку зрения по созданию фрейма данных. Еще раз спасибо!!