【问题标题】:how to insert sequential rows in data.table in R (Example given)?如何在 R 中的 data.table 中插入顺序行(给出示例)?
【发布时间】:2020-02-20 12:40:33
【问题描述】:

df 是 data.table 并且 df_expected 是期望的 data.table 。我想添加从 0 到 23 的小时列,对于新添加的小时,访问值将填充为 0。

df<-data.table(customer=c("x","x","x","y","y"),location_id=c(1,1,1,2,3),hour=c(2,5,7,0,4),visits=c(40,50,60,70,80))






df_expected<-data.table(customer=c("x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x",
                               "y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y",
                               "y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y","y"),

                    location_id=c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
                                  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
                                  3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3),

                    hour=c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
                           0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
                           0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23),

                    visits=c(0,0,40,0,0,50,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                             70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                             0,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0))

这是我试图获得的结果,但没有成功

df1<-df[,':='(hour=seq(0:23)),by=(customer)]
Error in `[.data.table`(df, , `:=`(hour = seq(0L:23L)), by = (customer)) : 
Type of RHS ('integer') must match LHS ('double'). To check and coerce would impact 
performance too much for the fastest cases. Either change the type of the target column, or 
coerce the RHS of := yourself (e.g. by using 1L instead of 1)

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    这是一种创建目标然后使用连接添加访问信息的方法。 ifelse 语句只是帮助清理合并中的 NA。您也可以保留它们,并在新的 data.table 中将它们替换为 :=

    target <- data.table(
      customer = rep(unique(df$customer), each = 24),
      hour = 0:23)
    
    df_join <- df[target, on = c("customer", "hour"), 
       .(customer, hour, visits = ifelse(is.na(visits), 0, visits))
       ]
    
    all.equal(df_expected, df_join)
    
    

    编辑:

    这解决了包含location_id 列的请求。一种方法是在创建目标时使用by=location。我还添加了 chinsoon12 回答中的一些代码。

    target <- df[ , .("customer" = rep(unique(customer), each = 24L),
                      "hour" = rep(0L:23L, times = uniqueN(customer))),
                  by = location_id]
    
    df_join <- df[target, on = .NATURAL, 
                  .(customer, location_id, hour, visits = fcoalesce(visits, 0))]
    
    all.equal(df_expected, df_join)
    

    【讨论】:

    • 感谢您的回答,尽管有一个查询.. 我还有一个名为“location_id”的列,它与客户列相关....就像 1 个客户可能有 3 个 location_ids,其他客户只有 1 个 location_id ....在这种情况下,我该如何更改上述脚本,因为具有 1 个位置的客户将重复 24 次,而具有 3 个位置的客户将重复 72 次(24*3)...。
    • 不客气。请参阅我的编辑以了解包含附加列的方法。
    【解决方案2】:

    另一个选项使用CJ 生成你的Universe,on=.NATURAL 用于连接同名列,fcoalesce 处理NA:

    df[CJ(customer, hour=0L:23L, unique=TRUE), on=.NATURAL, allow.cartesian=TRUE, 
        .(customer=i.customer, hour=i.hour, visits=fcoalesce(visits, 0))]
    

    【讨论】:

      【解决方案3】:

      这是一个 for 循环的答案。

      df_final <- data.table()
      for(i in seq(24)){
        if(i %in% df[,hour]){
          a <- df[hour==i]
        }else{
          a <- data.table(customer="x", hour=i, visits=0)}
      
        df_final <- rbind(df_final, a)
      }
      df_final
      

      您可以将其包装在另一个 for 循环中,让您的多个客户 x、y 等(以下循环不是很干净,但可以完成工作)。

      df_final <- data.table()
      
      for(j in unique(df[,customer])){
      
        for(i in seq(24)){
      
          if(i %in% df[,hour]){
            if(df[hour==i,customer] %in% j){
              a <- df[hour==i]
            }else{
              a <- data.table(customer=j, hour=i, visits=0)
            }
          }else{
            a <- data.table(customer=j, hour=i, visits=0)
          }
      
          df_final <- rbind(df_final, a)
        }
      }
      
      df_final
      

      【讨论】:

        猜你喜欢
        • 2021-01-11
        • 2013-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多