How about
as.data.frame(table(cut(x, breaks=c(y, Inf))))
Var1 Freq
1 2013-06-20 01:00:00 3
2 2013-06-20 01:02:00 0
3 2013-06-20 01:04:00 2
4 2013-06-20 01:06:00 0
Question
Two closely related posts are here and here. I haven't been able to translate either of these to my exact situation.
Here is a vector of times:
start.time = as.POSIXct("2013-06-20 01:00:00")
x = start.time + runif(5, min = 0, max = 8*60)
x = x[order(x)]
x
# [1] "2013-06-20 01:00:30 EDT" "2013-06-20 01:00:57 EDT"
# [3] "2013-06-20 01:01:43 EDT" "2013-06-20 01:04:01 EDT"
# [5] "2013-06-20 01:04:10 EDT"
Next, here is a vector of two-minute markers:
y = seq(as.POSIXct("2013-06-20 01:00:00"), as.POSIXct("2013-06-20 01:06:00"), 60*2)
y
# [1] "2013-06-20 01:00:00 EDT" "2013-06-20 01:02:00 EDT"
# [3] "2013-06-20 01:04:00 EDT" "2013-06-20 01:06:00 EDT"
I would like a quick, slick, scalable way to produce the counts of the elements of x
that fall in to the two-minute bins to the right of each element of y
, like this:
y count.x
1 2013-06-20 01:00:00 3
2 2013-06-20 01:02:00 0
3 2013-06-20 01:04:00 2
4 2013-06-20 01:06:00 0
Solution
How about
as.data.frame(table(cut(x, breaks=c(y, Inf))))
Var1 Freq
1 2013-06-20 01:00:00 3
2 2013-06-20 01:02:00 0
3 2013-06-20 01:04:00 2
4 2013-06-20 01:06:00 0
OTHER TIPS
Here is a function that solves the problem, and runs much faster than table(cut(...))
:
get.bin.counts = function(x, name.x = "x", start.pt, end.pt, bin.width){
br.pts = seq(start.pt, end.pt, bin.width)
x = x[(x >= start.pt)&(x <= end.pt)]
counts = hist(x, breaks = br.pts, plot = FALSE)$counts
dfm = data.frame(br.pts[-length(br.pts)], counts)
names(dfm) = c(name.x, "freq")
return(dfm)
}
The key line here is in the middle -- counts = hist(...
. The hist
function with the plotting option set to FALSE
does the crucial thing.
To test the speed performance of this function, I ran it as follows:
# First define x, a large vector of times:
start.time = as.POSIXct("2012-11-01 00:00:00")
x = start.time + runif(50000, min = 0, max = 365*24*3600)
x = x[order(x)]
# Apply the function, keeping track of running time:
t1 = Sys.time()
dfm = get.bin.counts(x, name.x = "time",
start.pt = as.POSIXct("2012-11-01 00:00:00"),
end.pt = as.POSIXct("2013-07-01 00:00:00"),
bin.width = 60)
as.numeric(Sys.time()-t1) #prints elapsed time
With this example, my function ran faster than table(cut(...))
by a little more than a factor of 10. Credit is due to the cut
help page, which states, "Instead of table(cut(x, br))
, hist(x, br, plot = FALSE)
is more efficient and less memory hungry."