有效地将多个 binary/categorical 列合并为 R 中的单个分类列

Efficiently combine multiple binary/categorical columns to single categorical column in R

首先,我知道以下页面上的相关问题/答案。

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

这里的objective是创建一个新的colum,将列出所有列的名称等于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

有人知道解决这个问题的一些软件包或有任何加速代码的建议吗?

这不是一个完美的解决方案,但应该能让您更快地实现目标。 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)