Изменение уровней внутренних факторов в R (важно для убежища - write_dta())
haven
Пакет предоставляет очень полезную функцию для экспорта фрейма данных /Tibble в Stata с помощью функции write_dta().
Когда коэффициент R записывается в Stata (с использованием функции write_dta()), внутренние уровни коэффициента R становятся числовым значением, сохраненным в длинном формате Stata, причем уровни записываются как метки переменных. (Эти внутренние уровни R-фактора такие же, как применение as.numeric(factor)
к фактору.)
Я хочу явно установить уровень внутреннего фактора R, чтобы иметь желаемые значения для числовых меток в Stata.
Проиллюстрировать:
eyes <- c("blue", "brown","green", "blue", "not disclose")
eyes_factor <- as.factor(eyes)
levels(eyes_factor)
#[1] blue brown green blue not disclose
#Levels: blue brown green not disclose
as.numeric(as.factor(eyes))
#[1] 1 2 3 1 4 # which is to be expected
Тем не менее, я хочу установить уровни внутренних факторов R в соответствии с очень специфической моделью. Например, я хочу внутренний уровень для:
синий = 2 и коричневый = 1 и зеленый = 6 пока не раскрываются = -1
Потому что это соответствует кодировке в анкете.
Я пытался использовать lvls_recode из forcats
пакет. Функция выглядит так:
forcats::lvls_reorder
function (f, idx, ordered = NA)
{
f <- check_factor(f)
if (!is.numeric(idx)) {
stop("`idx` must be numeric", call. = FALSE)
}
if (!setequal(idx, lvls_seq(f)) || length(idx) != nlevels(f)) {
stop("`idx` must contain one integer for each level of `f`",
call. = FALSE)
}
refactor(f, levels(f)[idx], ordered = ordered)
}
Но, как вы можете видеть здесь, новый idx, который мне нужен для конкретных, я не могу, потому что взяты только последовательные числа.
Глядя на stats::relevel()
тоже не решил проблему.
2 ответа
Если бы не -1 = disclose
, вы можете сделать это просто с чем-то вроде:
eyes2 <- factor(eyes,
levels = c("brown", "blue", paste0("not_used_", 1:3), "green", "not disclose"))
Это было бы именно то, что вы хотите, но not disclose
является 7
скорее, чем -1
, Одним из вариантов может быть сделать это таким образом, а затем перекодировать его в Stata. Вариант был бы заставить тех not disclose
значения должны быть NA
(например, просто не включая "не раскрывать" в качестве допустимого уровня) - не уверен, как это происходит в Stata.
R-факторы не могут иметь -1 в качестве одного из базовых кодов. Так что я не думаю, что есть простой способ обойти это. Вам придется самостоятельно их перекодировать, составив таблицу поиска. Например:
eye_codes <- data.frame(code = c(-1, 1, 2, 6),
level = c("not disclose", "brown", "blue", "green"),
stringsAsFactors = FALSE)
library(dplyr)
eyes3 <-left_join(data.frame(eyes), eye_codes, by = c("eyes" = "level"))
eyes3
Который получает вас:
eyes code
1 blue 2
2 brown 1
3 green 6
4 blue 2
5 not disclose -1
Столбец кода это то, что вы хотите здесь. Обратите внимание, я использовал dplyr::left_join
скорее, чем merge
иметь более контролируемое поведение упорядочения результата.
Это немного болезненно, конечно. Я бы сохранил данные из R как текстовый символ, не зависящий от платформы (вообще не факторы, которые кажутся слишком рискованными), а затем, если вам нужно, чтобы они были явно кодированы определенным образом в Stata, сделайте эту перекодировку в Стате.
Вы можете просто настроить справочную таблицу и выбрать правильные значения.
NewEyes = as.numeric(as.factor(eyes))
Replacements = c(2,1,6,-1)
Replacements[NewEyes]
[1] 2 1 6 2 -1