【问题标题】:R: Looping over rows until condition is met, then start over in next rowR:循环遍历行直到满足条件,然后在下一行重新开始
【发布时间】:2019-07-22 08:49:14
【问题描述】:

我有一个表格,每个客户的订单都带有时间戳。我想知道在下一个订单后在时间范围x 内发生了哪些订单,一旦时间范围结束,就从时间范围x 重新开始下一个订单。新列应始终说明哪一个是第一个订单。

最好看下面的例子。

我已经用next尝试了一些for loops,但根本无法使用。

数据如下:

x <- data.frame("Customer" =c(123,123,123,123,123,123,123,567), "Order_nr" = c(1,2,3,4,5,6,7,1), "Order_datetime" = c('2018-11-24 00:00:25','2018-11-24 15:58:23','2018-11-24 19:10:29','2018-11-24 21:29:04','2018-11-24 22:03:59','2018-11-24 22:26:59','2018-11-24 22:36:13','2018-11-24 12:00:55'))
x
| Customer | Order_nr | Order_datetime|
| ------------- |:-------------:| -----:|
| 123      | 1 | 2018-11-24 00:00:25 |
| 123      | 2 | 2018-11-24 15:58:23 |
| 123      | 3 | 2018-11-24 19:10:29 |
| 123      | 4 | 2018-11-24 21:29:04 |
| 123      | 5 | 2018-11-24 22:03:59 |
| 123      | 6 | 2018-11-24 22:26:59 |
| 123      | 7 | 2018-11-24 22:36:1 |
| 567      | 1 | 2018-11-24 12:00:55 |

如果我想知道1小时内的订单,我想在1h bundle first order列中得到结果,如果是3小时,它应该是3h bundle first order列的结果

| Customer | Order_nr | Order_datetime| 3h bundle first order| 3h bundle first order|
| ------------- |:-------------:| -----:|-----:|
| 123      | 1A | 2018-11-24 00:00:25 |1A |1A|
| 123      | 2A | 2018-11-24 15:58:23 |2A |2A|
| 123      | 3A | 2018-11-24 19:10:29 |3A |3A|
| 123      | 4A | 2018-11-24 21:29:04 |4A |3A|
| 123      | 5A | 2018-11-24 22:03:59 |4A |3A|
| 123      | 6A | 2018-11-24 22:26:59 |4A |4A|
| 123      | 7A | 2018-11-24 22:36:1  |5A |4A|
| 567      | 1B | 2018-11-24 12:00:55 |1B |1B|

所以我需要知道订单 4A、5A 和 6A 发生在从订单 4A 开始的 1h 内,例如 1h bundle first order

【问题讨论】:

    标签: r loops


    【解决方案1】:
    so <- data.frame("Customer" =c(123,123,123,123,123,123,123,567), 
                     "Order_nr" = c(1,2,3,4,5,6,7,1), 
                     "Order_datetime" = c('2018-11-24 00:00:25','2018-11-24 15:58:23',
                                          '2018-11-24 19:10:29','2018-11-24 21:29:04',
                                          '2018-11-24 22:03:59','2018-11-24 22:26:59',
                                          '2018-11-24 22:36:13','2018-11-24 12:00:55'))
    
    
    learn <- function(date_time, df, hr.within, i){
    
      subject <- abs(difftime(date_time, df$Order_datetime, units="hours"))
    
      ifelse(i ==1, 
             thatrow <- which((subject <= hr.within) == TRUE), 
             thatrow <- intersect( which((subject <= hr.within) == TRUE), 
                                   which((subject >= hr.within-1) == TRUE)))
    
      if(identical(thatrow, integer(0))) return()
    
      else{
        R2 <- df[thatrow, c("Customer", "Order_nr", "Order_datetime")]
        R2$x <- NA
        R2[,"x"] <- paste0(hr.within, "A")
        colnames(R2)[4] <- paste0(hr.within,"A bundle first order")
        return(R2)
      }
    }
    
    
    learn.wrapper <- function(date_time, df, hr.within=seq(1,100,1)){
      learn.out <- list()
      for(i in 1:length(hr.within)){
        learn.out[[i]] <- learn(date_time,so, hr.within[i], i)
      }
      return(rbindlist(learn.out, fill=TRUE))
    }
    
    learnery <- learn.wrapper('2018-11-24 19:00:00', df=so) #first argument is the time you want to ref. with
    learnery
    

    这假设所有操作都在 100 小时内发生,您可以通过 hr.within=seq(1,100,1) 重置到适当的持续时间窗口,然后重新编译。 然后,您可以在查看其输出时自行对结果进行行合并。

    【讨论】:

      【解决方案2】:

      一位同事帮我找到了解决办法:

      Order_nr_3h = [] 
      order1 = df['Order_nr ']
      initial_order = order1[0] ##initials needed so the loop can start with a value
      time = df['Order_datetime']
      initial = time[0]
      customer1 = df['customer']
      initial_customer = customer1[0]
      for i in range(-1,len(time)-1):
          delta = (time[i+1]-initial).seconds/3600 ## 1h
          if customer1[i+1] != initial_customer: 
              initial_order = order1[i+1]
              initial_customer = customer1[i+1] 
          if delta > 1: 
              initial = time[i+1]
              initial_order = order1[i+1]
              Order_nr_3h.append(initial_order)
          else:
              Order_nr_3h.append(initial_order)
              continue
      df['Order_nr_3h'] = Order_nr_3h
      

      然后,我在每个需要的时间间隔(1 小时、3 小时等)周围都有另一个循环

      【讨论】:

      • 你要求 R 并且你用 Python 回答了自己?
      猜你喜欢
      • 2022-01-01
      • 1970-01-01
      • 2016-11-16
      • 2019-07-05
      • 2018-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多