在列中减去一天中的时间(H:M形式)

时间:2016-07-22 13:55:10

标签: r

以下是我正在使用的原始数据的子集:

dput(datumi)
structure(c("21:26", "21:33", "21:38", "23:02", "23:03", "21:27", 
"21:34", "21:39", "23:03", "23:04", "21:26", "21:33", "21:38", 
"23:02", "23:04", "21:26", "21:34", "21:38", "23:02", "23:04", 
"21:27", "21:34", "21:39", "23:02", "23:04"), .Dim = c(5L, 5L
), .Dimnames = list(c("2", "3", "4", "5", "6"), c("Datum_1", 
"Datum_2", "Datum_3", "Datum_4", "Datum_5")))

所以我正在与时间一起工作,例如,21:26表示一天中的时间。

现在我想从第一列减去第二列,从第二列减去第三列,依此类推,这意味着我会从Datum_2Datum_1列中减去Datum_3Datum_2。来自Datum_4的1}}和Datum_3我的输出将是新列,差异为秒

如果我的数据是numeric,我已经创建了函数/循环,所以例如在数字数据的情况下,我会这样做并获得所需的输出:

dat <- data.frame(
  column1 =  round(runif(n = 10, min=0, max=5),0),
  column2 = round(runif(n = 10, min=0, max=5),0),
  column3 = round(runif(n = 10, min=0, max=5),0),
  column4 = round(runif(n = 10, min=0, max=5),0)
  )

results <- list()
for(i in 1:length(dat)) {
  if (i==length(dat)){
    results[[i]] <-dat[,i]
  } else {results[[i]] <-dat[,i+1] - dat[,i]}
}

results <- t(do.call(rbind,results))
results <- data.frame(results)

但我无法弄清楚时间格式,我尝试过strptimeas.POSIXct

x1 <- strptime(datumi, "%H:%M")
as.numeric(x1,units="secs")

 as.POSIXct(datumi,format="%H:%M")

还看了这个

Subtract time in r

Subtracting Two Columns Consisting of Both Date and Time in R

convert character to time in R

3 个答案:

答案 0 :(得分:2)

以下是基于answer中提供的R: Convert hours:minutes:seconds的一种解决方案。

datumi
#   Datum_1 Datum_2 Datum_3 Datum_4 Datum_5
# 2 "21:26" "21:27" "21:26" "21:26" "21:27"
# 3 "21:33" "21:34" "21:33" "21:34" "21:34"
# 4 "21:38" "21:39" "21:38" "21:38" "21:39"
# 5 "23:02" "23:03" "23:02" "23:02" "23:02"
# 6 "23:03" "23:04" "23:04" "23:04" "23:04"

makeTime <- function(x) as.POSIXct(paste(Sys.Date(), x))
dat <- apply(datumi, 2, makeTime)
mapply(x = 2:ncol(dat), 
       y = 1:(ncol(dat) -1), 
       function(x, y) dat[ , x] - dat[ , y])
#      [,1] [,2] [,3] [,4]
# [1,]   60  -60    0   60
# [2,]   60  -60   60    0
# [3,]   60  -60    0   60
# [4,]   60  -60    0    0
# [5,]   60    0    0    0

您也可以使用as.POSIXct,而不会使用&#39;格式&#39;来粘贴当前数据。参数:

makeTime <- function(x) as.POSIXct(x, format = "%H:%M")

注意,结果是相同的,因为as.POSIXct假定当前日期没有给出。

答案 1 :(得分:1)

如果您希望除了原始数据之外还有列名,您还可以这样做:

df<-as.data.frame(lapply(dat,strptime,format="%H:%M"))
lapply(1:4, function(i) df[,paste0("diff",i,"_",i+1)] <<- difftime(df[,i],df[,i+1],units=c("secs")))

df
              Datum_1             Datum_2             Datum_3             Datum_4             Datum_5  diff1_2 diff2_3  diff3_4
2 2016-07-22 21:26:00 2016-07-22 21:27:00 2016-07-22 21:26:00 2016-07-22 21:26:00 2016-07-22 21:27:00 -60 secs 60 secs   0 secs
3 2016-07-22 21:33:00 2016-07-22 21:34:00 2016-07-22 21:33:00 2016-07-22 21:34:00 2016-07-22 21:34:00 -60 secs 60 secs -60 secs
4 2016-07-22 21:38:00 2016-07-22 21:39:00 2016-07-22 21:38:00 2016-07-22 21:38:00 2016-07-22 21:39:00 -60 secs 60 secs   0 secs
5 2016-07-22 23:02:00 2016-07-22 23:03:00 2016-07-22 23:02:00 2016-07-22 23:02:00 2016-07-22 23:02:00 -60 secs 60 secs   0 secs
6 2016-07-22 23:03:00 2016-07-22 23:04:00 2016-07-22 23:04:00 2016-07-22 23:04:00 2016-07-22 23:04:00 -60 secs  0 secs   0 secs
   diff4_5
2 -60 secs
3   0 secs
4 -60 secs
5   0 secs
6   0 secs

答案 2 :(得分:0)

我找到了我的问题的解决方案,包括我为数字数据创建的函数/循环,我只需要包含

我的for循环函数中的

difftime(strptime(datumi[,i+1], format = "%H:%M"), strptime(datumi[,i], format = "%H:%M"), units = "secs")所以代码看起来像这样

datumi <- as.data.frame(datumi)
results <- list()
for(i in 1:length(dat)) {
  if (i==length(dat)){
    results[[i]] <-NULL
  } else {results[[i]] <-difftime(strptime(datumi[,i+1], format = "%H:%M"), strptime(datumi[,1], format = "%H:%M"), units = "secs")              }
}

results <- t(do.call(rbind,results))
results <- data.frame(results)

#And output
  X1 X2 X3 X4
2 60  0  0 60
3 60  0 60 60
4 60  0  0 60
5 60  0  0  0
6 60 60 60 60

但是因为@dayne使用的mapply对我来说更方便(因为它将函数应用于多个列表参数并且对我来说更具可读性)我使用了他的解决方案。