循环创建虚拟变量

时间:2016-10-15 12:48:51

标签: r loops dataset regression

我目前正在处理大型数据集(大约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分配给虚拟周的行。

Dummy示例(DW = Dummy Week):

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
}}}}

我知道这是错的,但是我无法解决我的问题。我很感激这方面的任何帮助。

2 个答案:

答案 0 :(得分:3)

我们可以使用model.matrix()包中的stats对您的数据进行虚假化处理。首先,我们需要将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的情况下运行它。

或者,您也可以使用dummyVars包中的caret。在这里, 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

答案 1 :(得分: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