Изменение уровней внутренних факторов в 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
Другие вопросы по тегам