在分类和NA变量中创建R中的二进制变量

时间:2014-09-11 18:11:13

标签: r binary

我有一个包含34个变量的12901 categoricalNA观测数据集。我将使用数据集通过聚类消费者人口统计数据来创建市场细分研究。

对于categorical变量,我想转换为numeric二进制数据。例如,变量HouseholdIncome有六个类别:50K-75k,75k-100k,35k-50k,100k-125k,150k-175k和其他。我希望将HouseholdIncome分解为六个变量(0,0,0,0,0,1),(0,0,0,0,1,0),(0,0,0,1) ,0,0),(0,0,1,0,0,0),(0,1,0,0,0,0)和(1,0,0,0,0,0)。

问题:如何将分类值更改为二进制变量,然后保留NA s?

我的机器:

> sessionInfo()
R version 3.1.0 (2014-04-10)
Platform: x86_64-apple-darwin13.1.0 (64-bit)

我的数据:

#Head of first six rows of the first six columns
> head(Store4df)
     Age Gender HouseholdIncome MaritalStatus PresenceofChildren HomeOwnerStatus
1  55-64 Female         50k-75k        Single                 No             Own
2   <NA> Female            <NA>          <NA>               <NA>            <NA>
3   <NA>   Male            <NA>          <NA>               <NA>            <NA>
4   <NA>   Male            <NA>          <NA>               <NA>            <NA>
5    65+   Male        75k-100k        Single                 No             Own
6   <NA> Female            <NA>          <NA>               <NA>            <NA>

我已阅读有关该命令的其他帖子,但没有一个有NA值的解决方案。我点了一个关于Creating new dummy variable columns from categorical variables的链接。我使用了第二个建议和二进制形式的数据,但代码中没有包含NA值。

> #Use model.matrix function to 
> binary1 <- model.matrix(~ factor(Store4df$HomeMarketValue) - 1)
> #Find which rows have NA values
> which(rowSums(is.na(binary1))==ncol(binary1))
# named integer(0)
> #Get head of model.matrix of two columns with five rows
> head(binary1, n=5)
   factor(Store4df$HomeMarketValue)100k-150k factor(Store4df$HomeMarketValue)150k-200k
1                                          0                                         0
2                                          0                                         0
3                                          1                                         0
4                                          0                                         0
5                                          0                                         0

编辑:我忘了发帖说我有两种类型的分类变量。一个包含类别和NA值,另一个包含TRUENA值。将TRUENA值变量放入model.matrix时出错。

> model.matrix(~ -1 + . , data = Store4df)
#Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) : 
  contrasts can be applied only to factors with 2 or more levels

这是变量的样子:

> che <- Store4df$Pets
> summary(che)
   Mode    TRUE    NA's 
logical    3535    9628 

将一个因子变量放入model.matrix

> data <- model.matrix(~  Pets, data = Store4df)
> summary(data)

  (Intercept)    PetsTRUE
 Min.   :1    Min.   :1  
 1st Qu.:1    1st Qu.:1  
 Median :1    Median :1  
 Mean   :1    Mean   :1  
 3rd Qu.:1    3rd Qu.:1  
 Max.   :1    Max.   :1  

如何在第10列和第12列中替换TRUE值?

3 个答案:

答案 0 :(得分:3)

我不认为model.matrix可以采用参数来详细说明如何处理丢失的数据但是,您可以将默认选项更改为na.pass,从而将缺失的值保留在{{1}中调用。

model.matrix

来自here

答案 1 :(得分:1)

对于解决方法,我要做的是将<NA>替换为&#34; Not Available&#34; (或者其他的东西)。然后,<NA>也将被视为因子级别。

copy <-Store4df
levels(copy$HomeMarketValue) <- c(levels(copy$HomeMarketValue),"Not Available")
copy$HomeMarketValue[is.na(copy$HomeMarketValue)]<-"Not Available"
binary1 <- model.matrix(~ factor(copy$HomeMarketValue) - 1)

请注意,我没有对上述内容进行测试,因为您没有提供可用于重现示例的数据。但是,现在你应该得到一个因子级虚拟变量,该变量为1,用于&#34;不可用&#34;。

举例来说:

A<-data.frame(ID=1:100,x=sample(c(1:5,NA),100,replace=TRUE))
A$x[is.na(A$x)]<-"NotAvailable"
MM<-model.matrix(~factor(A$x)-1)
for(i in 1:5) {
  MM[,i][MM[,6]==1]<-NA
}
MM<-MM[,-6]
head(MM)
##  factor(A$x)1 factor(A$x)2 factor(A$x)3 factor(A$x)4 factor(A$x)5
##1            0            0            1            0            0
##2            1            0            0            0            0
##3           NA           NA           NA           NA           NA
##4            1            0            0            0            0
##5            0            0            0            1            0
##6            0            0            0            1            0

答案 2 :(得分:1)

使用caret包很容易做到这一点 下面的代码是一次快速完成任意数量变量的方法。

require(caret)
# Make sure variables you are using are factors

VARS.TO.MAKE.DUMMY <-  #list of variables to convert to dummy
    c("HouseholdIncome", "Age")

dat.temp <- # Temporary data.frame to make dummies
    Store4df[,VARS.TO.MAKE.DUMMY]

dummy.vars <- # create dummies  
    predict(  
        dummyVars(  
            ~ .,   
            data = dat.temp
            ),
        newdata = dat.temp,
        na.action = na.pass
        )

Store4df <- # Append results to original dataframe
    cbind(Store4df, as.data.frame(dummy.vars))

rm(dummy.vars, dat.temp) # Garbage collection