R语言中生成虚拟变量/哑变量

本文介绍如何在R语言中处理分类变量(factor),并将其转换为虚拟变量(dummy variable)以适用于neuralnet等函数。通过使用model.matrix()和nnet包中的class.ind()函数进行转换。

转载自:http://iccm.cc/generate-dummy-variable-in-r-language/

在R语言中对包括分类变量(factor)的数据建模时,一般会将其自动处理为虚拟变量或哑变量(dummy variable)。但有一些特殊的函数,如neuralnet包中的neuralnet函数就不会预处理。如果直接将原始数据扔进去,会出现”requires numeric/complex matrix/vector arguments”需要数值/复数矩阵/矢量参数错误。

这个时候,除了将这些变量删除,我们只能手动将factor variable转换为取值(0,1)的虚拟变量。所用的函数一般有model.matrix(),nnet package中的class.ind()。

下面以UCI的german credit data为例说明。

首先,从UCI网站上下载到german.data数据集,并用str函数对其有个简单的认识。

download.file("http://archive.ics.uci.edu/ml/machine-learning-databases/statlog/german/german.data", 
    "./german.data")
data <- read.table("./german.data")
str(data)

该数据有21个变量,其中V21为目标变量,V1-V20中包括integer和factor两种类型。下面将用V1分类变量(包含4个level)和V2,V5,V8三个数值型变量作为解释变量建模。

## 'data.frame':    1000 obs. of  21 variables:
##  $ V1 : Factor w/ 4 levels "A11","A12","A13",..: 1 2 4 1 1 4 4 2 4 2 ...
##  $ V2 : int  6 48 12 42 24 36 24 36 12 30 ...
##  $ V3 : Factor w/ 5 levels "A30","A31","A32",..: 5 3 5 3 4 3 3 3 3 5 ...
##  $ V4 : Factor w/ 10 levels "A40","A41","A410",..: 5 5 8 4 1 8 4 2 5 1 ...
##  $ V5 : int  1169 5951 2096 7882 4870 9055 2835 6948 3059 5234 ...
##  $ V6 : Factor w/ 5 levels "A61","A62","A63",..: 5 1 1 1 1 5 3 1 4 1 ...
##  $ V7 : Factor w/ 5 levels "A71","A72","A73",..: 5 3 4 4 3 3 5 3 4 1 ...
##  $ V8 : int  4 2 2 2 3 2 3 2 2 4 ...
##  $ V9 : Factor w/ 4 levels "A91","A92","A93",..: 3 2 3 3 3 3 3 3 1 4 ...
##  $ V10: Factor w/ 3 levels "A101","A102",..: 1 1 1 3 1 1 1 1 1 1 ...
##  $ V11: int  4 2 3 4 4 4 4 2 4 2 ...
##  $ V12: Factor w/ 4 levels "A121","A122",..: 1 1 1 2 4 4 2 3 1 3 ...
##  $ V13: int  67 22 49 45 53 35 53 35 61 28 ...
##  $ V14: Factor w/ 3 levels "A141","A142",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ V15: Factor w/ 3 levels "A151","A152",..: 2 2 2 3 3 3 2 1 2 2 ...
##  $ V16: int  2 1 1 1 2 1 1 1 1 2 ...
##  $ V17: Factor w/ 4 levels "A171","A172",..: 3 3 2 3 3 2 3 4 2 4 ...
##  $ V18: int  1 1 2 2 2 2 1 1 1 1 ...
##  $ V19: Factor w/ 2 levels "A191","A192": 2 1 1 1 1 2 1 2 1 1 ...
##  $ V20: Factor w/ 2 levels "A201","A202": 1 1 1 1 1 1 1 1 1 1 ...
##  $ V21: int  1 2 1 1 2 1 1 1 1 2 ...

首先加载neuralnet包尝试一下,只用数值型变量建模,没有报错。

library("neuralnet")
NNModelAllNum <- neuralnet(V21 ~ V2 + V5 + V8, data)
NNModelAllNum


## Call: neuralnet(formula = V21 ~ V2 + V5 + V8, data = data)
## 
## 1 repetition was calculated.
## 
##         Error Reached Threshold Steps
## 1 104.9993578    0.005128715177    55

当我们把V1放入解释变量中出现了如下错误:

NNModel <- neuralnet(V21 ~ V1 + V2 + V5 + V8, data)


## Error: 需要数值/复数矩阵/矢量参数

此时可以用model.matrix函数将V1转化为三个虚拟变量,V1A12,V1A13,V1A14。

dummyV1 <- model.matrix(~V1, data)
head(cbind(dummyV1, data$V1))


##   (Intercept) V1A12 V1A13 V1A14  
## 1           1     0     0     0 1
## 2           1     1     0     0 2
## 3           1     0     0     1 4
## 4           1     0     0     0 1
## 5           1     0     0     0 1
## 6           1     0     0     1 4

因为model.matrix函数对数值型和分类Level=2的类别型变量没有影响,所以可以将四个变量一起用该函数生成新的数据集modelData,就可以用该数据集建模了。

modelData <- model.matrix(~V1 + V2 + V5 + V8 + V21, data)
head(modelData)


##   (Intercept) V1A12 V1A13 V1A14 V2   V5 V8 V21
## 1           1     0     0     0  6 1169  4   1
## 2           1     1     0     0 48 5951  2   2
## 3           1     0     0     1 12 2096  2   1
## 4           1     0     0     0 42 7882  2   1
## 5           1     0     0     0 24 4870  3   2
## 6           1     0     0     1 36 9055  2   1


NNModel <- neuralnet(V21 ~ V1A12 + V1A13 + V1A14 + V2 + V5 + V8, modelData)

另外一种方法来自nnet package的class.ind函数。

library("nnet")
dummyV12 <- class.ind(data$V1)
head(dummyV12)

可以看到,该结果和model.matrix稍有区别,生成了四个虚拟变量。要注意,为了避免多重共线性,对于level=n的分类变量只需选取其任意n-1个虚拟变量。

##      A11 A12 A13 A14
## [1,]   1   0   0   0
## [2,]   0   1   0   0
## [3,]   0   0   0   1
## [4,]   1   0   0   0
## [5,]   1   0   0   0
## [6,]   0   0   0   1
<think>好的,我现在要帮用户解决在Stata中生成虚拟变量的问题。首先,我需要回忆Stata中常用的方法,可能包括`tabulate`命令加`gen()`选项,或者`xi`前缀,还有`egen`的`cut()`函数。另外,用户提到他们之前看到引用里提到因子变量,可能`i.`前缀也是一个方法,尤其是在新版本中。 用户可能对基本操作不太熟悉,所以我需要从简单的方法开始。比如,使用`tabulate`自动生成虚拟变量,这是比较传统的方法。要确保举例清楚,比如分类变量是industry,生成多个虚拟变量,每个行业一个。这时候需要提醒用户注意虚拟变量陷阱,可能需要在回归时省略一个基准组。 然后,考虑更现代的方法,比如使用因子变量语法,比如`i.industry`直接在回归模型中,这样Stata会自动处理,可能用户不需要显式生成变量,节省内存工作量。但用户的问题是生成虚拟变量,所以可能需要两种情况的说明:生成变量本身或在模型中直接使用。 接下来,可能用户需要处理更复杂的情况,比如创建交乘项或者条件虚拟变量。这时候可以用`generate`配合逻辑条件,比如`gen high_income = income > 50000`,这样生成0-1变量。同时,交乘项可以直接用`var1#var2`或者更详细的语法,比如在回归中用`c.var1#i.var2`。 还要注意引用用户提供的参考内容,比如引用[1]提到生成虚拟变量交乘项的传统方法的问题,所以可以推荐使用因子变量的方法来提高效率,避免生成过多变量。引用[3]可能涉及赋值表达式,但不太直接相关,但引用[4]中的工具变量回归可能涉及变量生成,但这里可能暂时不需要。 可能还需要提醒用户注意事项,比如处理缺失值,设置基准组,避免多重共线性,以及大数据集时的内存问题。特别是使用`tabulate`时生成大量虚拟变量可能导致内存消耗,而因子变量方法更高效。 最后,生成相关问题需要考虑用户可能的后续问题,比如如何批量生成,处理多分类变量,或者如何在回归中正确引入虚拟变量而不出错。因此,相关问题可以包括因子变量的其他用法、交乘项的处理、虚拟变量陷阱等。</think>在 Stata 中创建虚拟变量主要有以下几种方法,具体操作如下: ### 1. **基础方法:`tabulate` 命令生成虚拟变量** 假设分类变量为 `industry`(行业代码),使用 `tabulate` 生成变量名+分类值为后缀的虚拟变量: ```stata tabulate industry, generate(dum_industry) ``` 这会自动生成 `dum_industry1`, `dum_industry2` 等虚拟变量,每个对应一个行业类别。需注意 **避免完全多重共线性**,实际使用时需手动省略一个基准组[^1]。 ### 2. **因子变量语法:直接建模(无需显式生成)** Stata 支持 `i.` 前缀直接在模型中使用分类变量,自动处理虚拟变量: ```stata reg y x i.industry ``` 此方法无需提前生成虚拟变量,节省内存且避免手动操作错误。 ### 3. **条件语句生成虚拟变量** 若需根据连续变量阈值创建虚拟变量(如收入高于5万元赋值为1): ```stata generate high_income = income > 50000 if !missing(income) ``` ### 4. **交乘项与多项式项** 使用 `#` 符号生成交乘项或平方项(例如教育年限与性别的交互效应): ```stata reg y c.education#i.gender ``` ### 5. **`egen` 函数进阶操作** 对分组变量进行复杂操作(如按分位数分组生成虚拟变量): ```stata egen income_group = cut(income), group(4) tabulate income_group, generate(dum_income) ``` ### 注意事项 - **缺失值处理**:需用 `if !missing(var)` 排除缺失值干扰 - **基准组设置**:默认以第一个类别为基准,可用 `ibn.` 或 `b(n).` 调整基准组 - **内存管理**:分类过多时建议使用因子变量语法而非显式生成[^1]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值