首先,我知道以下页面上的相关问题/答案。
Convert multiple binary columns to single categorical column
For each row return the column name of the largest value
但是我的问题略有不同,以上这些解决方案对我而言不起作用。
给出具有可能重叠的二进制变量的数据集,将它们组合为单个分类列的最有效方法是什么?
作为一个简单的示例,请考虑以下数据集
set.seed(12345)
d1<-data.frame(score=rnorm(10),
Male=sample(c(rep(1,5), rep(0,5))),
White=sample(c(rep(1,5),rep(0,5))),
college_ed = rep(c(1,0),5))
head(d1,5)
score Male White college_ed
1 0.5855288 1 0 1
2 0.7094660 1 1 0
3 -0.1093033 0 1 1
4 -0.4534972 0 1 0
5 0.6058875 1 1 1
此处的目标是创建一个新的列,该列将列出所有等于1的列的名称。
到目前为止,这是我想出的最好的解决方案,但我担心它有些粗糙,如果将其应用于更大的数据集,可能会效率不高。
grp_name<-function(x){
if(sum(x)==0){
z<- "None"
}else{
z<-paste(names(x[x==1]),collapse= "-")
}
return(z)
}
d1$demo<-apply(d1,1,grp_name)
score Male White college_ed demo
1 0.5855288 1 0 1 Male-college_ed
2 0.7094660 1 1 0 Male-White
3 -0.1093033 0 1 1 White-college_ed
4 -0.4534972 0 1 0 White
5 0.6058875 1 1 1 Male-White-college_ed
任何人都知道一些解决此问题的软件包,或者对加速代码有任何建议吗?
答案 0 :(得分:1)
这不是一个完美的解决方案,但可以让您更快地找到所需的东西。 if语句不向量化,而ifelse()可以向量化:请参见下文。...无需使用apply函数。
set.seed(12345)
d1<-data.frame(score=rnorm(10),
Male=sample(c(rep(1,5), rep(0,5))),
White=sample(c(rep(1,5),rep(0,5))),
college_ed = rep(c(1,0),5))
head(d1,5)
makeKey <- function(x,y,z){
s1 <- ifelse(x == 1,"Male", "")
s2 <- ifelse(y == 1, "White", "")
s3 <- ifelse(z == 1, "college_ed", "")
s4 <- paste(s1,s2,s3, sep = "-" )
return(s4)
}
d1$key <- makeKey(x=d1$Male, y=d1$White, z=d1$college_ed)