将数据框从分类变量重塑为仅二进制变量

时间:2019-04-20 10:01:27

标签: r

我有一个包含77列的数据集,其中一些具有分类值(例如,“性取向”列可以具有以下值之一:“异性恋”,“同性恋”,“双性恋”,“其他” ,'NA')。 (在重塑数据框之后,我还将估算一些NA)。

我想将此数据集转换为仅具有二进制值的数据集。 因此,例如,我希望将以上列分为4个不同的列,分别是:

Heterosexual    Homosexual    Bisexual     Other
1               0             0            0

或者,如果我有NA行,则希望将其表示为以下内容:

Heterosexual    Homosexual    Bisexual     Other
NA              NA            NA           NA

此外,我还有“性别”之类的“二进制”变量(我只有“男性”和“女性”值),并且我希望将此列拆分为两个不同的列,如下所示:

Male   Female
0      1

,或者在不适用的情况下:

Male   Female
NA     NA

有没有可以用来执行此操作的功能?我的教授告诉我,“重塑”功能可以帮助我完成此操作,但我在使用它时遇到了一些麻烦,我认为它不起作用。

能给我提些建议吗?预先谢谢你

1 个答案:

答案 0 :(得分:0)

您要创建的对象称为虚拟变量,R中的变量是使用model.matrix()创建的。但是,您的特定应用程序有点特殊,因此需要一些额外的摆弄。

dtf <- data.frame(id=20:24, 
                  f=c("a", "b", "c", "a", "b"), 
                  g=c("A", "C", NA, "B", "A"),
                  h=c("P", "R", "Q", NA, "Q"))

# (the first column is not a categorical variable, hence not included)
dtf2 <- dtf[-1]

# Pre-allocate a list of the appropriate length
l <- vector("list", ncol(dtf2))

# Loop over each column in dtf2 and 
for (j in 1:ncol(dtf2)) {
    # Make sure to include NA as a level 
    data <- dtf2[j]
    data[] <- factor(dtf2[,j], exclude=NULL)

    # Generate contrasts that include all levels
    cont <- contrasts(data[[1]], contrasts=FALSE)

    # Create dummy variables using the above contrasts, excluding intercept
    # Formula syntax is the same as in e.g. lm(), except the response
    # variable (term to the left of ~) is not included. 
    # '-1' means no intercept, '.' means all variables
    modmat <- model.matrix(~ -1+., data=data, contrasts.arg=cont)

    # Find rows to fill with NA
    nacols <- grep(".*NA$", colnames(modmat))

    # Only do the operations if an NA-column was found
    if (length(nacols > 0)) {
       narows <- rowSums(modmat[, nacols, drop=FALSE]) > 0
       modmat[narows,] <- NA
       modmat <- modmat[,-nacols]
    }

    l[[j]] <- modmat
}

data.frame(dtf[1], do.call(cbind, l))
#   id fa fb fc gA gB gC hP hQ hR
# 1 20  1  0  0  1  0  0  1  0  0
# 2 21  0  1  0  0  0  1  0  0  1
# 3 22  0  0  1 NA NA NA  0  1  0
# 4 23  1  0  0  0  1  0 NA NA NA
# 5 24  0  1  0  1  0  0  0  1  0