如何根据Date变量(YYYYMMDD)的月份添加虚拟变量Q1,Q2,Q3?

时间:2017-08-17 12:50:27

标签: 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(不完全相同的代码但尝试使用此逻辑创建变量):

df$Q1 <- ifelse(month(Date) = *"first month of every quarter"*,1,0)
df$Q2 <- ifelse(month(Date) = *"second month of every quarter"*,1,0)
df$Q3 <- ifelse(month(Date) = *"third month of every quarter"*,1,0)  
df$Q4 <- ifelse(month(Date) = *"fourth month of every quarter"*,1,0)  

但是这种方法并没有得到如上所述的矩阵。

请帮助相同或如果有更聪明的方法来实现这一点,请告诉我。

4 个答案:

答案 0 :(得分:1)

我们可以使用BEGIN TRANSACTION GO INSERT [form].[control](Id,Name,Title,ElementType,IsRequired,Length,MinValue,MaxValue,Mask,DefaultValue,OptionType,DbType,AddOn,AddOnBefore,ShowHide,ShowHideCtrlType,DisabledCtrl,DisabledCtrlType,IsActive,IsHidden,ParentId,CreatedBy,CreatedOn,UpdatedBy,Updatedon,Class,Multiple) VALUES('43',null,'Current Medical & Mental Health Diagnoses','2',null,null,null,null,null,null,null,'1',null,null,null,null,null,null,'1',null,null,'1',convert(datetime,'Jan 1 2016 12:00AM'),null,null,'15','0') update form.Control set class= NULL where id = 43 COMMIT TRANSACTION ;

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

答案 1 :(得分:0)

编辑:问题没有明确说明,OP的意图有不同的解释。现在,OP已澄清他是在下面的第二个答案之后。

答案1

问题从句子开始:我想创建4个虚拟变量,指每个季度为Q1,Q2,Q3,Q4,这取决于日期格式的销售月份加上一个样本矩阵。这可以解释为OP想要确定给定日期所属的季度并且以图形方式显示这个&#34;广泛的。

使用dcast()函数重塑以及quarter()中的lubridate函数可以实现此目的:

# 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")
        Date Q1 Q2 Q3 Q4
1 2017-01-01  1  0  0  0
2 2017-04-01  0  1  0  0
3 2017-07-01  0  0  1  0
4 2017-10-01  0  0  0  1

dcast()功能可从两个软件包中获得:reshape2data.table

答案2

如果OP在每个季度(即第1个月,第2个月或第3个月)要求中的月份,则以下是使用{{1}的替代解决方案} package将基数转换为序数

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")

答案 2 :(得分:0)

这是使用因子和model.matrix的基本R方法。最棘手的部分是正确设置季度因子变量的月份。

假设我们开始使用如下的字符向量。首先,转换为日期向量。

dates<- as.Date(dates, "%m/%d/%Y")

现在,将其放入data.frame并使用factor添加Quarter变量。

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

这里,模数运算符返回值0到3,其中3对应于季度中的第四个月,因此levels参数必须考虑到这一点。

现在,使用model.matrix创建二进制变量,并使用cbind添加它们。

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")

答案 3 :(得分:0)

使用great dummies包创建虚拟变量的另一个选项。只需要创建一个季度&#39;使用zoo包的列。

加载套餐:

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