【问题标题】:How to duplicate rows in R and add new data?如何在 R 中复制行并添加新数据?
【发布时间】:2018-05-31 18:23:51
【问题描述】:

我有一个时间戳数据的 data.table,其中包含人们的进出时间,四舍五入到最接近的 15 分钟间隔。我希望能够复制每一行以具有与其超时/超时数据所涵盖的 15 分钟间隔数相同的副本数,同时添加一个列出 15 分钟间隔的新列(例如,给定一个人在上午 10:00 打卡和在上午 11:00 打卡,将有四排,一排是上午 10:00,一排是上午 10:15,一排是上午 10:30,一排是上午 10:45)。

【问题讨论】:

标签: r


【解决方案1】:

我不知道您的数据是什么样的,但这是我最好的选择。

library(padr)
library(zoo)

#data
user<-"4"
times<-c("10:00","11:15")
times<-as.POSIXct(times,format="%H:%M")

#create df
dt<-data.frame(user,times)

> dt
  user               times
1    4 2018-05-31 10:00:00
2    4 2018-05-31 11:15:00

#make correct intervals
dt<-pad(dt, interval="15 min")

#carry user id forward
dt<-na.locf(dt)

>dt

  user               times
1    4 2018-05-31 10:00:00
2    4 2018-05-31 10:15:00
3    4 2018-05-31 10:30:00
4    4 2018-05-31 10:45:00
5    4 2018-05-31 11:00:00
6    4 2018-05-31 11:15:00

【讨论】:

    【解决方案2】:

    这实际上只是一个非常简单的转置应用和最后的观察结果。

    这是我的员工:

    emp <- data.frame(empid = 001, timein = as.POSIXct('2018-05-31 8:00'), timeout = as.POSIXct('2018-05-31 17:00'))
    

    这是我最后的观察结转包装(但也有zoo::na.locf

    locf <- function(y) c(NA, na.omit(y))[cumsum(!is.na(y))+1]
    

    现在转置:

    emplong <- reshape(emp, direction='long', idvar='empid', varying=list(2:3), 
      times=c('in', 'out'), timevar='status')
    

    这给出了:

          empid status              timein
    1.in      1     in 2018-05-31 08:00:00
    1.out     1    out 2018-05-31 17:00:00
    

    现在创建一个名册:

    roster <- data.frame('times' = seq(
      from=as.POSIXct('2018-05-31 00:00:00'),
      to=as.POSIXct('2018-06-01 00:00:00'),
      by=15*60))
    

    并合并

    roster <- merge(roster, emplong[, -1], by.x='times', by.x='timein', all=T)
    

    和 LOCF

    roster$status <- locf(roster$status )
    roster$status[is.na(roster$status )] <- 'out'
    

    这给出了:

    > roster
                     times status
    1  2018-05-31 00:00:00    out
    2  2018-05-31 00:15:00    out
    3  2018-05-31 00:30:00    out
    4  2018-05-31 00:45:00    out
    5  2018-05-31 01:00:00    out
    ...
    31 2018-05-31 07:30:00    out
    32 2018-05-31 07:45:00    out
    33 2018-05-31 08:00:00     in
    34 2018-05-31 08:15:00     in
    ...
    67 2018-05-31 16:30:00     in
    68 2018-05-31 16:45:00     in
    69 2018-05-31 17:00:00    out
    70 2018-05-31 17:15:00    out
    

    【讨论】:

      【解决方案3】:

      对于data.table 解决方案,假设您的data.table 格式如下:

      library(data.table)
      
      dt <- data.table(
        employee = c("John", "Paul", "Mary"),
        clock.in = as.POSIXct(c("10:30", "12:30", "13:15"), format = "%R"),
        clock.out = as.POSIXct(c("11:00", "13:15", "14:15"), format = "%R")
                       )
      
      > dt
         employee            clock.in           clock.out
      1:     John 2018-05-31 10:30:00 2018-05-31 11:00:00
      2:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00
      3:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00
      

      使用setkey 允许在基表和在上班和下班时间之间创建 15 分钟间隔序列的表之间建立连接:

      setkey(dt, employee)
      
      > dt[dt[, seq.POSIXt(clock.in, clock.out, by = 60*15), by = employee]]
          employee            clock.in           clock.out                  V1
       1:     John 2018-05-31 10:30:00 2018-05-31 11:00:00 2018-05-31 10:30:00
       2:     John 2018-05-31 10:30:00 2018-05-31 11:00:00 2018-05-31 10:45:00
       3:     John 2018-05-31 10:30:00 2018-05-31 11:00:00 2018-05-31 11:00:00
       4:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 13:15:00
       5:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 13:30:00
       6:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 13:45:00
       7:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 14:00:00
       8:     Mary 2018-05-31 13:15:00 2018-05-31 14:15:00 2018-05-31 14:15:00
       9:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00 2018-05-31 12:30:00
      10:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00 2018-05-31 12:45:00
      11:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00 2018-05-31 13:00:00
      12:     Paul 2018-05-31 12:30:00 2018-05-31 13:15:00 2018-05-31 13:15:00
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多