如何添加季节性虚拟变量?

How to add seasonal dummy variables?

我想根据季度在我的 R data.table 中添加季节性虚拟变量。我看过多个例子,但我还没有能够解决这个问题。我对 R 的了解有限,所以我想知道你是否能让我走上正轨。

我的 data.table 看起来像这样:

    Year_week  artist_id  number_of_events number_of_streams
   1:     16/30    8296         1            957892
   2:     16/33    8296         6            882282
   3:     16/34    8296         5            926037
   4:     16/35    8296         2            952704
   5:     15/37    17879        1             89515
   6:     16/22    22690        2            119653

我想要的是这样的格式:

 Year_week  artist_id  number_of_events number_of_streams Q2 Q3 Q4
   1:     16/50    8296         1            957892        0  0  1       

quarter 列添加到您的 df

df$quarter <- as.factor(df$quarter)
df <- cbind(df, model.matrix(~quarter, df))

希望这有效!

我假设 Year_week 是我们可以提取条目日期的地方。

library(data.table)

whichQuart <- function(x){
  data.frame(+(x <= 13),
    +(x >13 & x <= 26),
    +(x > 26 & x <= 39),
    +(x > 39 & x <= 52))
}

dt <-     setDT(read.table(text="Year_week  artist_id  number_of_events number_of_streams
1:     16/30    8296         1            957892
2:     16/33    8296         6            882282
3:     16/34    8296         5            926037
4:     16/35    8296         2            952704
5:     15/37    17879        1             89515
6:     16/22    22690        2            119653", header=TRUE, stringsAsFactors=FALSE))

dt[, week := strsplit(Year_week, "/")[2]]  
dt[, c("Q1", "Q2", "Q3", "Q4") := whichQuart(week)]

#   Year_week artist_id number_of_events number_of_streams week Q1 Q2 Q3 Q4
#1:     16/30      8296                1            957892   16  0  1  0  0
#2:     16/33      8296                6            882282   33  0  0  1  0
#3:     16/34      8296                5            926037   16  0  1  0  0
#4:     16/35      8296                2            952704   33  0  0  1  0
#5:     15/37     17879                1             89515   16  0  1  0  0
#6:     16/22     22690                2            119653   33  0  0  1  0

两种方法:

1) 使用 dcastcutsub:

dcast(DT[, Q := cut(as.integer(sub('.*/','',Year_week)),
                    breaks = c(0,13,26,39,53),
                    labels = paste0('Q',1:4))],
      Year_week + artist_id + number_of_events + number_of_streams ~ Q,
      value.var = 'Q',
      drop = c(TRUE,FALSE),
      fun = length)

给出:

   Year_week artist_id number_of_events number_of_streams Q1 Q2 Q3 Q4
1:     15/37     17879                1             89515  0  0  1  0
2:     16/22     22690                2            119653  0  1  0  0
3:     16/30      8296                1            957892  0  0  1  0
4:     16/33      8296                6            882282  0  0  1  0
5:     16/34      8296                5            926037  0  0  1  0
6:     16/35      8296                2            952704  0  0  1  0

这是做什么的:

  • as.integer(sub('.*/','',Year_week))Year_week 列中提取周数
  • 使用 cut 您可以使用适当的标签将其分成四等份(另请参阅 ?cut
  • 使用 dcast,您可以使用聚合函数 (length) 将四分之一列转换为宽格式。通过在 dcast 函数中使用 drop = c(TRUE,FALSE),您可以确保包含所有季度。

备注:

  • Q 列是有序因子,因此您也可以使用它来排列和过滤数据。
  • 取决于虚拟列的使用:您并不总是需要它们。当你想将它们用作分组或过滤变量时,你可以只使用 Q 变量。
  • 但是,一些统计测试需要虚拟变量(这证明了 dcast 步骤)。

2) 使用 cutsublapply:

DT[, Q := cut(as.integer(sub('.*/','',Year_week)),
              breaks = c(0,13,26,39,53),
              labels = paste0('Q',1:4))
   ][, paste0('Q',1:4) := lapply(paste0('Q',1:4), function(q) as.integer(q == Q))][]

这给出了类似的结果。无需使用 dcast 转置,您只需检查其中一个四分之一标签是否在 Q 列中。


已用数据:

DT <- fread(' Year_week  artist_id  number_of_events number_of_streams
     16/30    8296         1            957892
     16/33    8296         6            882282
     16/34    8296         5            926037
     16/35    8296         2            952704
     15/37    17879        1             89515
     16/22    22690        2            119653')