R: использование фактора
У меня есть некоторые данные:
transaction <- c(1,2,3);
date <- c("2010-01-31","2010-02-28","2010-03-31");
type <- c("debit", "debit", "credit");
amount <- c(-500, -1000.97, 12500.81);
oldbalance <- c(5000, 4500, 17000.81)
evolution <- data.frame(transaction, date, type, amount, oldbalance, row.names=transaction, stringsAsFactors=FALSE);
evolution$date <- as.Date(evolution$date, "%Y-%m-%d");
evolution <- transform(evolution, newbalance = oldbalance + amount);
evolution
Если я введу команду:
type <- factor(type)
где type
- номинальная (категориальная) переменная, то какая разница в моих данных?
Спасибо
Ответы
Ответ 1
Факторы против векторных векторов при выполнении статистики:
Что касается статистики, то нет никакой разницы в том, как R обрабатывает факторы и векторы символов. Фактически, его часто легче оставить фактор-переменные в качестве символьных векторов.
Если вы выполняете регрессию или ANOVA с lm() с символьным вектором в качестве категориального
переменная, вы получите нормальный вывод модели, но с сообщением:
Warning message:
In model.matrix.default(mt, mf, contrasts) :
variable 'character_x' converted to a factor
Факторы против векторных векторов при манипулировании кадрами данных:
Однако при манипулировании файлами данных характерные векторы и факторы трактуются очень по-разному. Некоторую информацию о раздражениях R и факторах можно найти в блоге Quantum Forest, R-ловушка № 3: факторы friggin.
Полезно использовать stringsAsFactors = FALSE
при чтении данных из .csv или .txt с помощью read.table
или read.csv
. Как отмечено в другом ответе, вы должны убедиться, что все в вашем символьном векторе согласовано, иначе каждая опечатка будет обозначаться как другой фактор. Вы можете использовать функцию gsub() для исправления опечаток.
Вот пример, показывающий, как lm() дает вам те же результаты с
символьный вектор и коэффициент.
Случайная независимая переменная:
continuous_x <- rnorm(10,10,3)
Случайная категориальная переменная в виде символьного вектора:
character_x <- (rep(c("dog","cat"),5))
Преобразуйте вектор символов в факторную переменную.
factor_x < - as.factor(character_x)
Введите две категории случайных значений:
character_x_value <- ifelse(character_x == "dog", 5*rnorm(1,0,1), rnorm(1,0,2))
Создайте случайную связь между независимыми переменными и зависимой переменной
continuous_y <- continuous_x*10*rnorm(1,0) + character_x_value
Сравните вывод линейной модели с фактор-переменной и символом
вектор. Обратите внимание на предупреждение, которое задается символьным символом.
summary(lm(continuous_y ~ continuous_x + factor_x))
summary(lm(continuous_y ~ continuous_x + character_x))
Ответ 2
Все зависит от того, на какой вопрос вы запрашиваете данные!
type.c <- c("debit", "debit", "credit")
type.f <- factor(type.c)
Здесь type.c - это просто список строк символов, тогда как type.f - это список факторов (это правильно? или это массив?)
storage.mode(type.c)
# [1] "character"
storage.mode(type.f)
# [1] "integer"
когда создается фактор-переменная, он просматривает все значения, которые были заданы, и создает "уровни"... загляните в:
levels(type.f)
# [1] "credit" "debit"
Затем вместо хранения символьных строк "дебет" "кредит" "неправильно записанный debbit" и т.д.... он просто сохраняет целое число вместе с уровнями... смотрите:
str(type.f)
# Factor w/ 2 levels "credit","debit": 2 2 1
то есть. в type.c говорится: c ( "дебет" , "дебет" , "кредит" ) и уровни (тип .f) говорят "кредит" "дебет" , вы видите, что str (type.f) начинает перечислять первые несколько значения по мере их сохранения, т.е. 2 2 1...
Если вы неправильно наберете "debbit" и добавите его в список, а затем выполните уровни (type.f), вы увидите его как новый уровень... иначе вы могли бы сделать таблицу (type.c).
Когда в списке всего три элемента, это не имеет большого значения для объема хранилища, но по мере того, как ваш список увеличивается, "кредит" (6 символов) и "дебет" (5 символов) начнут принимать чем у 4 байтов для хранения целого числа (плюс пара байтов). Небольшой эксперимент показывает, что для случайно выбранного набора type.c пороговое значение для объекта object.size(type.c) > object.size(type.f) составляет около 96 элементов.
dc <- c("debit", "credit")
N <- 300
# lets store the calculations as a matrix
# col1 = n
# col2 = sizeof(character)
# col3 = sizeof(factors)
res <- matrix(ncol=3, nrow=N)
for (i in c(1:N)) {
type.c <- sample(dc, i, replace=T)
type.f <- factor(type.c)
res[i, 1] <- i
res[i, 2] <- object.size(type.c)
res[i, 3] <- object.size(type.f)
cat('N=', i, ' object.size(type.c)=',object.size(type.c), ' object.size(type.f)=',object.size(type.f), '\n')
}
plot(res[,1], res[,2], col='blue', type='l', xlab='Number of items in type.x', ylab='bytes of storage')
lines(res[,1], res[,3], col='red')
mtext('blue for character; red for factor')
cat('Threshold at:', min(which(res[,2]>res[,3])), '\n')
Извинения за недостаток R'ness, поскольку я думал, что это поможет с ясностью.
Ответ 3
Тип будет преобразован из символа в коэффициент. Основное различие заключается в том, что факторы имеют предопределенные уровни. Таким образом, их значение может быть только одним из этих уровней или NA. В то время как символы могут быть чем угодно.