在这里选择问题的答案:
用dplyr创建一个因子变量?
没有给哈德利留下深刻的印象,对于我遇到的一些问题,后续的回答也不能很好地概括。我想知道社区是否可以通过一个更简单的示例做得更好:
### DATA ### A = round(runif(200,0,1),0) B = c(1 - A[1:100],rep(0,100)) C = c(rep(0,100), 1 - A[101:200]) dummies <- as.data.frame(cbind(A,B,C)) header <- c("Christian", "Muslim", "Athiest") names(dummies) <- header ### ONE WAY ### dummies$Religion <- factor(ifelse(dummies$Christian==1, "Christian", ifelse(dummies$Muslim==1, "Muslim", ifelse(dummies$Athiest==1, "Athiest", NA))))
解决方案模仿上面链接中提供给OP的结果。有没有更简单的函数将虚拟变量折叠为一个因子变量,例如STATA中的egen group函数?一个简单的班轮会很棒。
使用Akrun的解决方案和系统时间(谢谢):
set.seed(24) A = round(runif(2e6,0,1),0) B = c(1 - A[1:1e6],rep(0,1e6)) C = c(rep(0,1e6), 1 - A[1000001:2000000]) dummies <- as.data.frame(cbind(A,B,C)) header <- c("Christian", "Muslim", "Athiest") names(dummies) <- header attach(dummies) #Alistaire system.time({ dummies %>% rowwise() %>% transmute(religion = names(.)[as.logical(c(Christian, Muslim, Athiest))]) }) # user system elapsed # 56.08 0.00 56.08 system.time({ dummies %>% transmute(religion = case_when( as.logical(Christian) ~ 'Christian', as.logical(Muslim) ~ 'Muslim', as.logical(Athiest) ~ 'Atheist')) }) # user system elapsed # 0.22 0.04 0.27 #Curt F. system.time({ dummies %>% gather(religion, is_valid) %>% filter(is_valid == T) %>% select(-is_valid) }) # user system elapsed # 0.33 0.03 0.36 #Akrun system.time({ names(dummies)[as.matrix(dummies)%*% seq_along(dummies)] }) # user system elapsed # 0.13 0.06 0.21 system.time({ names(dummies)[max.col(dummies, "first")] }) # user system elapsed # 0.04 0.07 0.11
我发现Akrun的解决方案是最快的方法,并提供了2条单线。然而,许多感谢别人对自己的独特方法的问题和编码方法的慷慨供应,我想更多地了解,尤其是使用的%%
,names(.)
,is_valid
和qdapTools包。
使用dplyr的快速方法是
dummies %>% rowwise() %>% transmute(religion = names(.)[as.logical(c(Christian, Muslim, Athiest))])
不过,哈德利在该答案中真正抱怨的是嵌套ifelse
结构。他是case_when
为取代它而建造的:
dummies %>% transmute(religion = case_when( as.logical(Christian) ~ 'Christian', as.logical(Muslim) ~ 'Muslim', as.logical(Athiest) ~ 'Atheist'))