有效地将多个 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)
首先,我知道以下页面上的相关问题/答案。
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)