改变 R 中的内部因素水平(对避风港很重要 - write_dta())

Changing internal factor levels in R (important for haven - write_dta())

haven 包提供了一个非常有用的功能,可以使用 write_dta() 函数将数据 frame/Tibble 导出到 Stata。

当一个 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

因为这与问卷上的编码相符。

我尝试使用 forcats 包中的 lvls_recode。 该函数如下所示:

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()也没有解决问题

如果不是 -1 = disclose,你可以简单地用类似的东西来做到这一点:

eyes2 <- factor(eyes, 
           levels = c("brown", "blue", paste0("not_used_", 1:3), "green", "not disclose"))

这正是您想要的,但 not disclose7 而不是 -1。一种选择是这样做,然后在 Stata 中重新编码。一个变体是强制那些 not disclose 值是 NA (例如只是不包括 "not disclose" 作为有效级别) - 不确定如何进入 Stata。

R 因素不能将 -1 作为基础代码之一。所以我认为没有任何简单的方法可以解决这个问题。您必须自己重新编码,查找 table。例如:

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 中以特定方式明确编码它们,请重新编码在 Stata 中。

您可以设置查找 table 和 select 正确的值。

NewEyes = as.numeric(as.factor(eyes)) 
Replacements = c(2,1,6,-1)
Replacements[NewEyes]
[1]  2  1  6  2 -1