我想创建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)
但是这种方法并没有得到如上所述的矩阵。
请帮助相同或如果有更聪明的方法来实现这一点,请告诉我。
答案 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已澄清他是在下面的第二个答案之后。
问题从句子开始:我想创建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()
功能可从两个软件包中获得:reshape2
和data.table
。
如果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))