我有一个包含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
有没有可以用来执行此操作的功能?我的教授告诉我,“重塑”功能可以帮助我完成此操作,但我在使用它时遇到了一些麻烦,我认为它不起作用。
能给我提些建议吗?预先谢谢你
答案 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