【问题标题】:How create binary variable by comparison between row columns如何通过行列之间的比较来创建二进制变量
【发布时间】:2018-02-28 20:19:32
【问题描述】:

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

> 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 是否在第一行给出的区间 Jan,Apr,Jul,Oct PromoInterval 变量的行。

所以我创建了一个新的变量 result ,将 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 列给出的月份名称是否确实存在于变量 list 中。例如,如果resultat 的第一行的juilJan,Apr,Jul,Oct 中,由PromoInterval 的第一行给出。

所以我创建了这个二进制变量:

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

请问我该如何解决? 提前谢谢你!

【问题讨论】:

    标签: r data.table


    【解决方案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=" ")
    

    【讨论】:

    • 感谢您的提议,但它给出的列为零!!
    • dat[1,as.numeric(grepl(format(Date,"%b"),PromoInterval))] 提供了什么?
    • 它为零:> data[1,as.numeric(grepl(format(Date,"%b"),PromoInterval))] [1] 0
    • 第一行的日期是否包括在内?即grepl(format(dat$Date,"%b"),dat$PromoInterval)。如果这是FALSE,则表示您正在查看的月份不包括在 Jan、April、Jun、Oct 中
    • 你会做什么 any(grepl(format(as.Date(Date),"%b") 因为如果你想从日期中提取月份数,我认为它应该是 as.numeric(strftime(Date, format="%m"))
    【解决方案2】:

    这应该会给你一些解决这个问题的先机。

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

    【讨论】:

    • 感谢您的努力,但 month_name 提供的是 juil. 而不是 Jul
    猜你喜欢
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    相关资源
    最近更新 更多