我一直在处理一个目前包含89个列的数据集,其中43个因子列的级别最多为15个。我想知道是否有一种方法可以抓取所有列 - 找到因子变量并将它们分解为二进制列。到目前为止,我已经能够在stackoverflow上从我的搜索中找到一些代码,但是我还没有能够以正确的方式将它们组合在一起。
首先,我将使用starwars数据集
data <- starwars
lapply(data, class)
data$hair_color <- as.factor(data$hair_color)
data$skin_color <- as.factor(data$skin_color)
data$eye_color <- as.factor(data$eye_color)
要将单个变量分解为二进制,我将使用以下
for (i in unique(data$hair_color)){
data[,paste0(i)]=ifelse(data$hair_color==i,1,0)
}
我可以将列放在可以使其更容易的列表中
w <- which( sapply( data, class ) == 'factor' )
创建上面的函数(我无法超越这一点)
createbin <- function(x){
for (i in unique(x)){
data[,paste0(i)]=ifelse(x==i,1,0)
}
}
现在将其应用于整个列表
lapply(data[,w], createbin)
这不起作用,所以任何帮助将不胜感激
答案 0 :(得分:1)
我不完全确定你要做什么。也许比factor
数据集中starwars
级更少的简单样本数据集会有所帮助。
无论哪种方式,我认为model.matrix
可能是您问题的关键。
例如,我们可以首先为所有factor
级别生成二进制模型矩阵:
w <- which(sapply(data, class) == 'factor');
# Create model matrix for all factors
df <- as.data.frame.matrix(model.matrix(
as.formula(sprintf("name ~ 0 + %s", paste0(names(w), collapse = "+"))),
data = data));
对于最终data.frame
,我们然后cbind
原始data.frame
减去factor
列,以及所有factor
级别的模型矩阵。
df <- cbind.data.frame(data[, -w], df);
为了说明,让我们举一个更简单的例子。
# Sample data
data <- data.frame(
x = 1:12,
y = 11:22,
z = gl(3, 4, 12, c("factorA", "factorB", "factorC")));
# x y z
#1 1 11 factorA
#2 2 12 factorA
#3 3 13 factorA
#4 4 14 factorA
#5 5 15 factorB
#6 6 16 factorB
#7 7 17 factorB
#8 8 18 factorB
#9 9 19 factorC
#10 10 20 factorC
#11 11 21 factorC
#12 12 22 factorC
所有factor
列的索引。
w <- which(sapply(data, class) == 'factor');
w;
#z
#3
构建模型矩阵:
# Model matrix
df <- as.data.frame.matrix(model.matrix(
as.formula(sprintf("x ~ 0 + %s", paste0(names(w), collapse = "+"))),
data = data));
具有二进制data.frame
级别的最终factor
:
df <- cbind.data.frame(data[, -w], df);
# x y zfactorA zfactorB zfactorC
#1 1 11 1 0 0
#2 2 12 1 0 0
#3 3 13 1 0 0
#4 4 14 1 0 0
#5 5 15 0 1 0
#6 6 16 0 1 0
#7 7 17 0 1 0
#8 8 18 0 1 0
#9 9 19 0 0 1
#10 10 20 0 0 1
#11 11 21 0 0 1
#12 12 22 0 0 1