如何添加季节性虚拟变量?
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) 使用 dcast
、cut
和 sub
:
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) 使用 cut
、sub
和 lapply
:
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')
我想根据季度在我的 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) 使用 dcast
、cut
和 sub
:
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) 使用 cut
、sub
和 lapply
:
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')