如何通过行列之间的比较来创建二进制变量

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列给出的月份名称是否确实存在于变量列表中。例如,如果第一排juilresultat在第一排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

以上是关于如何通过行列之间的比较来创建二进制变量的主要内容,如果未能解决你的问题,请参考以下文章

如何创建片段以重复变量编号中的代码行

如何更改片段中的主要活动变量

JS创建文件并上传服务器

如何检查连续变量和分类变量之间的相关性?

这几种 VSCode 扩展是我最喜欢的

片段和活动之间的核心区别是啥?哪些代码可以写成片段?