循环创建虚拟变量

Loop to create dummy variables

我目前正在处理一个大型数据集(约 30k 行),并且正在创建 hedonic 回归。下一步是创建每周虚拟变量。

现在我的数据已经根据测量数据的日期分配了每周编号。有 50 个不同的周(1-52,2 个失踪下落不明)。这些每周数字会重复,直到大约 10 rows, 之后发生变化,但它们也会重复出现,因为新产品类别是衡量指标。数据集中有 132 个可用,其中一个类别包含 100 - 300 rows

这是数据集的一个例子

UPC         Weeks
1111112016  1
1111112016  1
1111112016  2
1111112016  2
1111112016  3
1111112016  3
1111112440  1
1111112440  1
1111112440  2
1111112440  2
1111112440  3
1111112440  3

现在为了创建虚拟变量,我创建了 50 列,每列有大约 30k 行来表示数据集。每当虚拟周(因此列名)和实际周(原始数据集的行)相等时,我想将 1 分配给虚拟周的行。

示例虚拟(DW = 虚拟周):

DW1 DW2 
NA  NA
NA  NA
NA  NA

我尝试了以下方法:

for (i in 1:seq(Soap$WEEK)){
if Soap$WEEK[i] == seq(from=1, by=1, to=52){
for (j in names(x)){
x$DW[[j]] = 1
else {
  x$DW[[j]] = 0
}}}}

我知道这是错误的,但是我无法解决我的问题。我将不胜感激在这件事上的任何帮助。

您可以通过使用 sapply 并将 Weeks 列的值与您可以使用 substr 提取的虚拟列名称的数字部分进行比较来解决此问题。

在您的示例数据集上:

# create the dummy columns and fill them with NA's
dat[, paste0('DW', 1:3)] <- NA

# compare the values in 'Weeks' with the numeric part of the column names
dat[, 3:5] <- sapply(names(dat)[3:5], function(x) as.integer(substr(x,3,3) == dat$Weeks))

结果:

> dat
          UPC Weeks DW1 DW2 DW3
1  1111112016     1   1   0   0
2  1111112016     1   1   0   0
3  1111112016     2   0   1   0
4  1111112016     2   0   1   0
5  1111112016     3   0   0   1
6  1111112016     3   0   0   1
7  1111112440     1   1   0   0
8  1111112440     1   1   0   0
9  1111112440     2   0   1   0
10 1111112440     2   0   1   0
11 1111112440     3   0   0   1
12 1111112440     3   0   0   1

我们可以使用 stats 包中的 model.matrix() 来虚拟化您的数据。首先,我们需要将 Weeks 转换为 factor 列。

df$Weeks <- as.factor(df$Weeks)

现在我们可以运行 model.matrix():

model.matrix(~ Weeks + UPC + 0, data = df)
#   Weeks1 Weeks2 Weeks3        UPC
#1       1      0      0 1111112016
#2       1      0      0 1111112016
#3       0      1      0 1111112016
#4       0      1      0 1111112016
#5       0      0      1 1111112016
#6       0      0      1 1111112016
#7       1      0      0 1111112440
#8       1      0      0 1111112440
#9       0      1      0 1111112440
#10      0      1      0 1111112440
#11      0      0      1 1111112440
#12      0      0      1 1111112440

您也可以只使用 model.matrix(~ . + 0 , data = df),因为数字列会被自动忽略。公式中的+ 0避免用Intercept替换第一层。要查看差异,请尝试在不使用 0.

的情况下 运行

或者,您也可以使用 caret 包中的 dummyVars。这里,no Intercept 是默认行为:

library(caret)

dm <- dummyVars(" ~ .", data = df)
data.frame(predict(dm, newdata = df))
#          UPC Weeks.1 Weeks.2 Weeks.3
#1  1111112016       1       0       0
#2  1111112016       1       0       0
#3  1111112016       0       1       0
#4  1111112016       0       1       0
#5  1111112016       0       0       1
#6  1111112016       0       0       1
#7  1111112440       1       0       0
#8  1111112440       1       0       0
#9  1111112440       0       1       0
#10 1111112440       0       1       0
#11 1111112440       0       0       1
#12 1111112440       0       0       1