代码之家  ›  专栏  ›  技术社区  ›  STP

更改R中的内部因素级别(对于haven-write\u dta()很重要)

  •  2
  • STP  · 技术社区  · 6 年前

    这个 haven 包提供了一个非常有用的函数,用于使用write\u dta()函数将数据帧/TIBLE导出到Stata。

    将R因子写入Stata(使用write\u dta()函数)时,内部R因子级别将成为以Stata long格式保存的数值,级别将写入变量标签。(这些内部R系数水平与应用相同 as.numeric(factor) 达到一定程度。)

    我想显式地设置R的内部因子级别,以便在Stata中获得numlabel所需的值。

    举例说明:

    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 包裹 函数如下所示:

    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 回复  |  直到 6 年前
        1
  •  3
  •   Peter Ellis    6 年前

    如果不是因为 -1 = disclose ,您只需执行以下操作即可:

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

    那正是你想要的但是 not disclose 7 而不是 -1 . 一种选择是这样做,然后在Stata中重新编码。一种变体是强制 不披露 待处理的值 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中以特定方式显式编码,请在Stata中重新编码。

        2
  •  0
  •   G5W    6 年前

    您只需设置一个查找表并选择正确的值即可。

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