有效地将多个二元/分类列组合到R中的单个分类列

时间:2018-11-30 00:27:19

标签: r data-manipulation binary-data categorical-data

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

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

任何人都知道一些解决此问题的软件包,或者对加速代码有任何建议吗?

1 个答案:

答案 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)