R 如何根据日期变量的月份(YYYYMMDD)添加虚拟变量Q1、Q2、Q3?
我想创建4个虚拟变量,将每个季度称为Q1、Q2、Q3、Q4,这将取决于日期格式的销售月份 大概是这样的:R 如何根据日期变量的月份(YYYYMMDD)添加虚拟变量Q1、Q2、Q3?,r,date,R,Date,我想创建4个虚拟变量,将每个季度称为Q1、Q2、Q3、Q4,这将取决于日期格式的销售月份 大概是这样的: Date Q1 Q2 Q3 Q4 01/01/2017 1 0 0 0 02/01/2017 0 1 0 0 03/01/2017 0 0 1 0 04/01/2017 0 0 0 1 我尝试使用lubridate包使用month(date)提取销售日期月份,然后尝试在这些行上创建虚拟变量Q1、Q2、Q3、Q4(代码不完全相同
Date Q1 Q2 Q3 Q4
01/01/2017 1 0 0 0
02/01/2017 0 1 0 0
03/01/2017 0 0 1 0
04/01/2017 0 0 0 1
我尝试使用lubridate包使用month(date)提取销售日期月份,然后尝试在这些行上创建虚拟变量Q1、Q2、Q3、Q4(代码不完全相同,但尝试使用此逻辑创建变量):
df$Q1我们可以使用tidyverse
library(tidyverse)
df1 %>%
mutate(Qs = paste0("Q", month(mdy(Date))), ind = 1) %>%
spread(Qs, ind, fill = 0)
# Date Q1 Q2 Q3 Q4
#1 01/01/2017 1 0 0 0
#2 02/01/2017 0 1 0 0
#3 03/01/2017 0 0 1 0
#4 04/01/2017 0 0 0 1
数据
df1编辑:问题没有明确说明,OP的意图也有不同的解释。现在,OP已经澄清他是在寻找下面的第二个答案
答复1
问题从这句话开始:我想创建4个虚拟变量,将每个季度称为Q1、Q2、Q3、Q4,这取决于日期格式的销售月份加上样本矩阵。这可以解释为OP希望确定给定日期所属的季度,并以广泛的格式“图形化”显示该季度
这可以通过使用dcast()
函数重塑形状和lubridate
中的quarter()
函数来实现:
# create sample data
DF <- data.frame(Date = seq(as.Date("2017-01-01"), length.out = 4, by = "3 months"))
# reshape
data.table::dcast(DF, Date ~ paste0("Q", lubridate::quarter(DF$Date)), length,
value.var = "Date")
dcast()
函数可从两个软件包中获得:restrape2
和data.table
答复2
如果OP要求每个季度内的月数,即第一个月、第二个月或第三个月,这里有一个替代解决方案,它使用toOrdinal
包将基数转换为序数
DF <- data.frame(Date = seq(as.Date("2017-01-01"), length.out = 12, by = "1 months"))
month_in_quarter <- function(x)
sprintf("%s_M_in_Qtr", sapply((month(x) - 1) %% 3 + 1, toOrdinal::toOrdinal))
data.table::dcast(DF, Date ~ month_in_quarter(Date), length, value.var = "Date")
下面是一个使用因子和model.matrix
的基本R方法。最棘手的部分是正确设置季度因素变量的月份
假设我们从一个字符向量开始,如下所示。首先,转换为日期向量
dates<- as.Date(dates, "%m/%d/%Y")
这里,模数运算符返回值0到3,其中3对应于季度中的第四个月,因此levels参数必须考虑到这一点
现在,使用model.matrix
创建二进制变量,并使用cbind
将其固定
dat <- cbind(dat, model.matrix(~mnthQrtr-1, dat))
数据
dates <- c("01/01/2017", "02/01/2017", "03/01/2017", "04/01/2017")
dates使用greatdummies
包创建虚拟变量的另一个选项。只需要使用zoo
包创建一个“季度”列
加载包:
require(dummies)
require(zoo)
创建一些测试数据:
df<-data.frame(date =seq(as.Date("2017/1/1"), as.Date("2017/4/1"), "months"))
这不是OP想要的。我们的目标是在每个季度内获得当月头寸的指标,因此从1月到12月,您需要c(1,2,3,1,2,2,3,3,3,3,3,1,2,3)
并以此为基础构建指标。@lmo抱歉,我以为这是他们想要的季度数据。谢谢,在进一步阅读中更正,它不是完全清楚。看起来他们可能会问两个问题。uwe block已经要求他们澄清,但到目前为止还没有回应。这不是OP要求的。我们的目标是在每个季度内获得当月头寸的指标,因此从1月到12月,您需要c(1,2,3,1,2,3,1,2,31,2,3)
,并以此为基础构建指标。@lmo是的,我承认可能是这样。然而,问题中所示的矩阵将具有极大的误导性,那么,这是真的。这个矩阵混淆了任何一种解释。此外,OP在表达他们想要的东西时并不一致。这可能是一个由两部分组成的问题。。。我想我集中在第二部分“现在我想创建虚拟变量,Q1,Q2,Q3为”,然后是ifelse
伪代码。现在还不清楚他们是否完成了他们的第一个目标,这正是你回答的重点。谢谢@UweBlock和其他人。我知道问题没有说清楚,但我真的很感谢你的帮助!这个解决方案的第二部分对我有效。Qx
变量的含义我不清楚。在预期结果中,有四个变量Q1
到Q4
,但在代码段中只有三个。@UweBlock:由于自由度的原因,不创建Q4变量。一年中有4个季度,在建模创建中只使用3个。所以,你只想创建3个变量,但你的问题从我想创建4个虚拟变量开始,每个季度指的是Q1、Q2、Q3、Q4。矩阵显示了四列。这仍然令人困惑。然而,有不同的答案(我的答案包含两种不同的方法)。也许,您可以指出哪些答案返回了预期的结果。
dat <- data.frame(Date=dates,
mnthQrtr=factor(as.integer(format(dates, "%m")) %% 3,
levels=c(1:2, 0), labels=c(paste0("MQ", c(1:3)))))
dat <- cbind(dat, model.matrix(~mnthQrtr-1, dat))
dat
Date mnthQrtr mnthQrtrMQ1 mnthQrtrMQ2 mnthQrtrMQ3
1 2017-01-01 MQ1 1 0 0
2 2017-02-01 MQ2 0 1 0
3 2017-03-01 MQ3 0 0 1
4 2017-04-01 MQ1 1 0 0
dates <- c("01/01/2017", "02/01/2017", "03/01/2017", "04/01/2017")
require(dummies)
require(zoo)
df<-data.frame(date =seq(as.Date("2017/1/1"), as.Date("2017/4/1"), "months"))
df$Quarter<-format(as.yearqtr(df$date), "Q%q")
df<-dummy.data.frame(df, sep="_")
colnames(df)<-gsub("Quarter_", "", colnames(df))