Как преобразовать факторную переменную в числовую - используя R
У меня есть еще одна проблема и надеюсь на вашу помощь. Я уже гуглил, спросил друга и попытался понять похожие проблемы / вопросы вокруг этого сайта, но я до сих пор не могу понять это...
Итак, вот моя проблема: у меня большой набор данных, который охватывает данные за 1980-2012 годы. Я использовал функцию read.spss, чтобы получить данные в R
rohdaten <-read.spss("C:\\Users\\xxxxxxx.sav", use.value.labels = TRUE, to.data.frame = TRUE,
max.value.labels = Inf, trim.factor.names = FALSE,
trim_values = TRUE, reencode = NA, use.missings = TRUE)
Это похоже на работу. Затем я хотел бы проанализировать переменную 14 (v14), которая является шкалой Ликерта, переходящей от "полностью согласен" к "не согласен вообще" и поэтому закодирована как фактор. Я хотел бы сравнить изменение ответов на эту шкалу Ликерта с течением времени, и поэтому я хочу вычислить среднее значение этого, и для этого оно должно быть числовым. Это первый шаг вопроса... Согласно R для чайников мне нужно сначала изменить коэффициент на символ, а затем изменить его на числовой. Хорошо... вот мой код... Сначала я попробовал функцию recode(), которая не работала - затем я просто продолжил и создал новый объект "econ", который создает переменную типа 14 в копии. (поэтому я не влияю на исходные данные v14 в рабочей области)
rohdaten$v14_2 <- recode(rohdaten$v14, "8 = NA; 9 = NA; 0 = NA; 1 = 1; 2 = 2; 3 = 3; 4 = 4; 5 = 5; as.factor.result = FALSE") #should recode already - kinda doesn't work
class(rohdaten$v14_2) #just tells me it's a factor...
str(rohdaten$v14_2)
econ <- rohdaten$v14_2
Имея в виду "для чайников-сайтов", я превращаю вещи в символы, а затем в цифры
str(econ)
as.character(econ)
head(econ)
econ <- as.numeric(econ)
head(econ)
По какой-то причине это дает мне "хороший" результат, несмотря на "ошибку" (??) в строке "как символ"... Если я пойду с econ <- as.character(econ)
- Я получаю "Предупреждающее сообщение: НС введены путем принуждения" после econ <- as.numeric(econ)
команда...
Хорошо, пока, кажется, работает как-то, я думаю!?
Но затем я хочу вычислить среднее значение для каждого года (который находится в переменной 2), и я наткнулся на функцию by()
похоже, он делает именно то, что я хочу, поэтому мой код оказался:
avgEconRat <- by(data = rohdaten, INDICES = rohdaten$v2, FUN = mean, na.rm = T)
head(avgEconRat) #actually gives me some means - not sure though whether it's the real means or the means of the "factor-number" that's mentioned in the "for-dummies-website" - sorry I can't explain it better :-(
Теперь у меня, похоже, есть данные в объекте avgEconRat, но, во-первых, я не уверен, что мое среднее значение вообще верно, а во-вторых, и это как-то главная проблема, как мне теперь обратиться к моим данным для построения графика Это?
p1 <- ggplot(na.action=na.exclude, rohdaten, aes(v14, v2))
p1 + geom_point(aes(color = v652), alpha = 0.6) +
facet_grid(. ~ v5)
Это код, который я имел в виду - и я знаю, что сейчас мне придется заменить "rohdaten" на "econ", но, поскольку я понятия не имею, как устроен "econ" (и также не знаю, как это выяснить,), Я абсолютно застрял здесь:-/ Я чувствую, что у меня есть (или может быть, в зависимости от того, являются ли мои средства правильными...) данные, которые мне нужны, но я как бы потерял доступ к ним.
Извините за мои странные проблемы, но обучение программированию без реального наставничества довольно сложно без какого-либо предыдущего опыта.
Большое спасибо за ваше терпение, время и помощь!
2 ответа
Во-первых, вот почему вы должны были бы преобразовать в символ перед преобразованием в числовой:
Допустим, у нас есть фактор, который содержит несколько чисел
x = factor(c(1,2,7,7))
Вы можете проверить, как это представлено в R следующим образом:
unclass(x)
#> [1] 1 2 3 3
#> attr(,"levels")
#> [1] "1" "2" "7"
и вы увидите, что есть 3 уровня, и что значения представлены в виде индексов для этих 3 уровней. Кроме того, если вы позвоните as.numeric()
непосредственно, вы получаете индексный вектор, а не значения, на которые вы надеялись:
as.numeric(x)
#> [1] 1 2 3 3
С другой стороны, если у вас есть шкала Ликерта, а уровни факторов находятся в правильном порядке:
f = factor(c("agree","agree","somewhat agree","somewhat agree","somewhat disagree","disagree","disagree"))
levels(f)
#> [1] "agree" "disagree" "somewhat agree" "somewhat disagree"
вы можете на самом деле хотите индекс:
#> as.numeric(f)
[1] 1 1 3 3 4 2 2
Однако, если ваши уровни вышли из строя, как в:
f = factor(sample(c("agree","somewhat agree","somewhat disagree","disagree"),
20,
TRUE))
levels(f)
#> [1] "agree" "disagree" "somewhat agree" "somewhat disagree"
тогда вместо звонка as.numeric(as.character(f))
(что в данном случае не имеет смысла), вам нужно изменить порядок уровней факторов, а затем вызвать as.numeric, например, так:
as.numeric(factor(f,
# specifify the levels in the correct order:
levels=c("agree","somewhat agree","somewhat disagree","disagree"))
У меня была похожая проблема с набором данных 1988-2012 гг., Но я пытался изменить имена переменных в числа. После нескольких часов проб разных комбинаций - я тоже очень плохо знаком с R- я нашел следующее решение.
Сначала я делал это:
для этого требуется пакет "plyr"
library(plyr)
my.data2$islamic_leviathan_score <- revalue(my.data2$islamic_leviathan,
c("(1) Very Suitable"="3", "(2) Suitable"="2", "(3) Somewhat Suitable"="1", "(4) Not Suitable At All"="-1"))
Значения были правильными, но R не распознавал переменную как числовую. Поэтому было невозможно нарисовать гистограмму или регрессию.
Тогда я сделал это:
Исламский левиафан
my.data2$islamic_leviathan <- c("3", "2", "1", "-1")
my.data2$islamic_leviathan_score <- as.factor(my.data2$islamic_leviathan)
my.data2$islamic_leviathan_score
my.data2$islamic_leviathan_score_1 <-as.numeric(as.character(my.data2$islamic_leviathan_score))
my.data2$islamic_leviathan_score_1
Эта операция изменила переменную с коэффициента на числовую, но проблема в том, что все результаты (значения переменной) были изменены после этой операции, и поэтому мои результаты были полностью неверными.
То, что я только что сделал - и казалось, что решил проблему - это:
library(plyr)
my.data2$islamic_leviathan_score <- revalue(my.data2$islamic_leviathan,
c("(1) Very Suitable"="3", "(2) Suitable"="2", "(3) Somewhat Suitable"="1", "(4) Not Suitable At All"="-1"))
my.data2$islamic_leviathan_score_1 <- as.numeric(as.character(my.data2$islamic_leviathan_score))
Я использовал смесь обеих попыток, переоценивая потенциальные значения при преобразовании переменной в числовые. Полученные результаты теперь соответствуют исходным значениям, содержащимся в наборе данных, когда переменные являются факторными переменными. Вы можете использовать это решение, чтобы изменить имя переменных на любое другое, преобразовав их в числовые переменные.