如何通过行列

时间:2018-02-28 20:19:33

标签: r data.table

我的数据表中有几个月的列,显示连续几个月的间隔。

> 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 日期是否在第一行的 1月,4月,7月,10月区间内 PromoInterval 变量的一行。

所以我创建了一个新的变量结果,将 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中。

所以我创建了这个binairy变量:

data[,Promoinsales:=if(resultat %in% list) {1} else {0}]

但是结果全为空且不正确,因为第一行应该是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

我该如何解决这个问题? 提前谢谢你!

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

这应该会给你一些解决这个问题的开端。

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