R 从假人创建因子变量的最简单方法

R 从假人创建因子变量的最简单方法,r,dplyr,R,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("Christia

此处为问题的选定答案:

没有给哈德利留下深刻印象,对于我遇到的一些问题,后续的答案也不能很好地概括。我想知道社区是否可以用一个简单的例子做得更好:

  ### 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))))
####数据###
A=圆形(runif(200,0,1),0)
B=c(1-A[1:100],代表(0100))
C=C(代表(0100),1-A[101:200])
假人我们可以使用

dummies$Religion <- names(dummies)[as.matrix(dummies)%*% seq_along(dummies)]
如果有行只有0个元素,则

dummies$Religion <- names(dummies)[max.col(dummies, "first")*NA^(!rowSums(dummies))]

使用dplyr的快捷方法是

dummies %>% rowwise() %>% 
    transmute(religion = names(.)[as.logical(c(Christian, Muslim, Athiest))])
哈雷在这个答案中真正抱怨的是嵌套的
ifelse
结构。他在
替换它时构建了
case\u:

dummies %>% transmute(religion = case_when(
    as.logical(Christian) ~ 'Christian', 
    as.logical(Muslim) ~ 'Muslim', 
    as.logical(Athiest) ~ 'Atheist'))

如果OP的主要目的是创建
宗教
列,则可通过一次调用直接完成:

Religion <- sample(c("Christian", "Muslim", "Atheist"), 200, replace = TRUE, 
                   prob = c(60, 20, 20))

但是,如果出于某种原因需要使用
dummies
data.frame,则可以使用以下代码从
宗教
向量创建它:

mat <- sapply(unique(Religion), function(x) as.integer(Religion == x))
dummies <- cbind(as.data.frame(mat), Religion)
请注意,对于不同的
sample()
运行,结果可能会有所不同,因为在调用
sample()
之前,我们没有使用
set.seed()


从中,我从package
qdapTools
了解了
mtabulate()
函数,它可以用一行代码替换
sapply()
构造:

dummies <- cbind(qdapTools::mtabulate(Religion), Religion)

dummies一种方法是将
tidyr
dplyr
结合起来。这可能不会提供最快的性能(我没有检查),但对我来说,至少它提供了最容易理解的代码

从OP中的
假人
数据帧开始:

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", "Atheist")
names(dummies) <- header
这个版本的好处在于它没有对初始数据帧的单发性做任何假设。如果初始帧中的某一行同时是无神论者和基督徒,则输出将有两行

table(Religion)
#Religion
#  Atheist Christian    Muslim 
#       37       115        48 
mat <- sapply(unique(Religion), function(x) as.integer(Religion == x))
dummies <- cbind(as.data.frame(mat), Religion)
head(dummies)
#  Muslim Christian Atheist  Religion
#1      1         0       0    Muslim
#2      1         0       0    Muslim
#3      0         1       0 Christian
#4      1         0       0    Muslim
#5      0         1       0 Christian
#6      0         0       1   Atheist
dummies <- cbind(qdapTools::mtabulate(Religion), Religion)
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", "Atheist")
names(dummies) <- header
require(tidyr)
require(dplyr)
dummies %>% 
    gather(religion, is_valid) %>% 
    filter(is_valid == T) %>%
    select(-is_valid)