我在SO找到了答案,但这对我不起作用。我想要的是如下:
c_id c_time
1 2012-08-15 00:00:30
1 2012-08-15 00:01:21
1 2012-08-15 00:01:25
2 2012-08-15 00:02:40
2 2012-08-15 00:03:41
我想在小时,分钟或秒中获得c_id变量的第一次和最后一次出现之间的时间差。
c_diff
00:00:55
00:01:01
非常感谢任何帮助!
答案 0 :(得分:4)
这是一个简单的问题,即通过不同的c_id对时间进行分组并获取最大值和最小值之间的差值。 有几种方法可以做到这一点,我更喜欢使用d_dlyr包的group_by函数。
#sample data
#dput(df)
df<-df<-structure(list(c_id = c(1, 1, 1, 2, 2), c_time = structure(c(1344988830,
1344988881, 1344988885, 1344988960, 1344989021), class = c("POSIXct",
"POSIXt"), tzone = "GMT")), .Names = c("c_id", "c_time"), row.names = c(NA,
-5L), class = "data.frame")
library(dplyr)
out<-summarize(group_by(df, c_id), delta=difftime(max(c_time), min(c_time), units = "mins"))
要将列增量转换为所需格式,您需要使用chron包:
library(chron)
zero <- structure(0, units = "secs", class = "difftime")
dd.day <- as.vector((out$delta + zero)/(24*60*60))
out$delta<-times(dd.day)
out
# Source: local data frame [2 x 2]
#
# c_id delta
# (dbl) (tims)
# 1 1 00:00:55
# 2 2 00:01:01
应该有一种更简单的方法,但我在2005年的一篇文章中找到答案(http://grokbase.com/t/r/r-help/055n2qa21v/r-print-format-for-difftime)
答案 1 :(得分:3)
tapply可能有帮助。
>c_id <- c(1,1,1,2,2)
>c_time <- as.POSIXct(c("2012-08-15 00:00:30","2012-08-15 00:01:21","2012-08-15 00:01:25","2012-08-15 00:02:40","2012-08-15 00:03:41"))
>c_diff <- tapply(c_time, c_id, function(x) max(as.numeric(x))-min(as.numeric(x)))
>c_diff
1 2
55 61
答案 2 :(得分:2)
获得差异很简单:只需减去,即max(df$c_time) - min(df$c_time)
。但是,在将其应用于多个子集时,您可能会发现单位变得不稳定,因此明确使用difftime
以便设置单位是一个好主意。在aggregate
:
aggregate(c_time ~ c_id, df, function(x){difftime(max(x), min(x), units ='secs')})
# c_id c_time
# 1 1 55
# 2 2 61
但是,这不是您想要的时间格式。 chron
有一个很好的时间类,假设你不只是想使用字符串。它减去了比difftime
aggregate(c_time ~ c_id, df, function(x){x <- chron::as.chron(x); max(x) - min(x)})
# c_id c_time
# 1 1 00:00:55
# 2 2 00:01:01
# or in dplyr
library(dplyr)
df %>% mutate(c_time = chron::as.chron(c_time)) %>%
group_by(c_id) %>%
summarise(range = max(c_time) - min(c_time))
# Source: local data frame [2 x 2]
#
# c_id range
# (int) (tims)
# 1 1 00:00:55
# 2 2 00:01:01
# or data.table
library(data.table)
setDT(df)[, .(c_id, c_time = chron::as.chron(c_time))
][, .(range = max(c_time) - min(c_time)), by = c_id]
# c_id range
# 1: 1 00:00:55
# 2: 2 00:01:01
或者使用data.table
的ITime而不是chron::times
,尽管它在减去时会返回秒数:
setDT(df)[, .(c_id, c_time = as.ITime(c_time))
][, .(range = as.ITime(as.POSIXct(max(c_time) - min(c_time),
'UTC', origin))), by = c_id]
# c_id range
# 1: 1 00:00:55
# 2: 2 00:01:01
如果你确实想要字符串而不是格式化时间,你实际上可以将它保存在所有基数R中:
aggregate(c_time ~ c_id, df,
function(x){format(as.POSIXct(as.numeric(difftime(max(x),
min(x),
units ='secs')),
'UTC', origin = origin),
'%T')})
# c_id c_time
# 1 1 00:00:55
# 2 2 00:01:01