如何通过行列之间的比较来创建二进制变量
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过行列之间的比较来创建二进制变量相关的知识,希望对你有一定的参考价值。
我在数据表中有这个月的列,显示了连续几个月的间隔。
> data[,"PromoInterval"]
PromoInterval
1: Jan,Apr,Jul,Oct
2: Jan,Apr,Jul,Oct
3: Jan,Apr,Jul,Oct
4: Jan,Apr,Jul,Oct
5: Jan,Apr,Jul,Oct
---
324322: Jan,Apr,Jul,Oct
324323: Jan,Apr,Jul,Oct
324324: Jan,Apr,Jul,Oct
324325: Jan,Apr,Jul,Oct
324326: Jan,Apr,Jul,Oct
然后我想检查下面给出的日期是否在相应的区间内,假设所有基数的每一行都是在同一年给出的。
日期列是:
> data[,"Date"]
Date
1: 2015-07-31
2: 2015-07-30
3: 2015-07-29
4: 2015-07-28
5: 2015-07-27
---
324322: 2013-01-05
324323: 2013-01-04
324324: 2013-01-03
324325: 2013-01-02
324326: 2013-01-01
例如,我需要知道第一行的2015-07-31日期是否在PromoInterval变量的第一行给出的Jan,Apr,Jul,Oct区间。
所以我创建了一个新的变量结果,将Date变量给出的月份转换为真实名词:
data[,resultat:=as.character(month(ymd(010101) + months((data[,DateMonth])-1),label=TRUE,abbr=TRUE))]
> data[,"resultat"]
resultat
1: juil\.
2: juil\.
3: juil\.
4: juil\.
5: juil\.
---
324322: janv\.
324323: janv\.
324324: janv\.
324325: janv\.
324326: janv\.
但我不知道为什么格式如上所述?
然后我创建一个列表,使PromoInterval成为每行的列表类型:
data[,list:=strsplit((data[,PromoInterval]),split=',',fixed=TRUE)]
然后我比较一下resultat列给出的月份名称是否确实存在于变量列表中。例如,如果第一排juil
的resultat
在第一排Jan,Apr,Jul,Oct
给出的PromoInterval
中。
所以我创建了这个二进制变量:
data[,Promoinsales:=if(resultat %in% list) {1} else {0}]
但结果都是null并且不正确,因为第一行应该是1而不是0!(7->Jul
列表中存在Jan,Apr,Jul,Oct
)
> data[,"Promoinsales"]
Promoinsales
1: 0
2: 0
3: 0
4: 0
5: 0
---
324322: 0
324323: 0
324324: 0
324325: 0
324326: 0
我该如何解决这个问题?先感谢您!
答案
dat[,promoinSales:=as.numeric(grepl(month.abb[month(Date)],PromoInterval)),by=1:nrow(dat)][]
nrow Date PromoInterval promoinSales
1: 1 2015-06-27 Jan,Apr,Jul,Oct 0
2: 2 2015-05-27 Jan,Apr,Jul,Oct 0
3: 3 2015-04-27 Jan,Apr,Jul,Oct 1
4: 4 2015-01-27 Jan,Apr,Jul,Oct 1
5: 5 2015-10-27 Jan,Apr,Jul,Oct 1
6: 6 2015-12-27 Jan,Apr,Jul,Oct 0
dat[,promoinSales:=as.numeric(grepl(format(as.Date(Date),"%b"),PromoInterval)),by=1:nrow(dat)][]
数据:
dat=fread(" Date PromoInterval
2015-06-27 Jan,Apr,Jul,Oct
2015-05-27 Jan,Apr,Jul,Oct
2015-04-27 Jan,Apr,Jul,Oct
2015-01-27 Jan,Apr,Jul,Oct
2015-10-27 Jan,Apr,Jul,Oct
2015-12-27 Jan,Apr,Jul,Oct
",sep=" ")
另一答案
这应该会给你一些解决这个问题的开端。
## this function checks if month name is present in PI
check_values <- function(x,y)
{
y_val <- unlist(strsplit(y, split = ','))
if(x %in% y_val) return(1)
else return (0)
}
## add column in df2 since both df have same rows
df2[, PI := df1$PromoInterval]
## extract month from Date column
df2[, month_name := months(as.Date(Date), abbreviate = T)]
## get result
df2[, result := mapply(check_values, month_name, PI)]
## first few rows of output
Date month_name PI result
1: 2015-07-31 Jul Jan,Apr,Jul,Oct 1
2: 2015-07-30 Jul Jan,Apr,Jul,Oct 1
3: 2015-07-29 Jul Jan,Apr,Jul,Oct 1
4: 2015-07-28 Jul Jan,Apr,Jul,Oct 1
5: 2015-07-27 Jul Jan,Apr,Jul,Oct 1
以上是关于如何通过行列之间的比较来创建二进制变量的主要内容,如果未能解决你的问题,请参考以下文章