Reputation: 37
I have a large data set that looks like:
Time,Volume
1996-02-05 00:34:00,0.01
1996-02-05 00:51:00,0.01
1996-02-05 00:52:00,0.01
1996-02-05 01:04:00,0.01
1996-02-05 01:19:00,0.01
1996-02-05 05:00:00,0.01
1996-02-05 05:07:00,0.01
1996-02-05 05:08:00,0.01
1996-02-05 05:14:00,0.01
I'd like to sum the Volume
column for each 30 minute interval. This is what I've tried:
z <- read.zoo("precip.csv", header = TRUE, sep = ",", FUN = as.chron)
half_hour <- period.apply(z, endpoints(z, "minutes", 30), length)
Which returned:
Time,Volume
02/05/96 00:52:00,3
02/05/96 01:19:00,2
02/05/96 05:14:00,4
I'm trying to get the output to look like:
Time,Volume
02/05/96 00:29:00,0
02/05/96 00:59:00,3
02/05/96 01:29:00,2
02/05/96 01:59:00,0
02/05/96 02:29:00,0
02/05/96 02:59:00,0
...and so on.
Alternatively, I think it would work if I could fill in the original data set so that every minute is accounted for (where missing Volumes
equal 0).
I found this post, but couldn't make it work.
> z_xts<- xts(precip[,c("Volume")],precip[,"Time"])
Error in xts(precip[, c("Volume")], precip[, "Time"]) :
order.by requires an appropriate time-based object
Upvotes: 3
Views: 645
Reputation: 89
I was a little confused about step 3) mentioned above, so I what I did is:
library("lubridate")
library("xts")
my_data <- read.csv("my_data.csv", stringsAsFactors=FALSE, sep=",",
header=T)
colnames(my_data) <- c("Time", "PAR", "NDVI", "LWS")
#It is easier if you subset your data
my_data_short_short <- subset(my_data, select = c("Time", "NDVI"))
my_data_short$Time <- ymd_hm(my_data_short$Time, tz="UTC")
beginning <- as.POSIXct("2016-05-12 00:00",format = "%Y-%m-%d %H:%M",
tz="UTC")
end <- as.POSIXct("2016-06-05 00:00",format = "%Y-%m-%d %H:%M", tz="UTC")
timesteps <- seq(beginning, end, by="5 min")
volume <- rep_len(1, length.out=length(timesteps))
time_series <- data.frame(timesteps, volum)
merge <- merge(time_series, my_data_short, by.x= "timesteps", by.y="Time",
all.x=TRUE, all.y = FALSE)
#This formats your data to run the package xts
my_data_brief.xts <- xts(x= merge$NDVI, order.by=merge$timesteps, frequency
= 1, tzone="UTC")
# Align all index values to 30-minute intervals
a <- align.time(my_data_brief.xts, 60*30)
# 5) Sum the values for Volume in each period
result <- period.apply(a, endpoints(a, "minutes", 30), sum, na.rm=TRUE)
saveRDS (result, file="result.rds")
Upvotes: 0
Reputation: 176648
This should do what you want:
library(xts)
x <- as.xts(read.zoo(text="Time,Volume
1996-02-05 00:34:00,0.01
1996-02-05 00:51:00,0.01
1996-02-05 00:52:00,0.01
1996-02-05 01:04:00,0.01
1996-02-05 01:19:00,0.01
1996-02-05 05:00:00,0.01
1996-02-05 05:07:00,0.01
1996-02-05 05:08:00,0.01
1996-02-05 05:14:00,0.01",
sep=",", FUN=as.POSIXct, header=TRUE, drop=FALSE))
# 1) Create POSIXct sequence from midnight of the first day
# until the end of the last day
midnightDay1 <- as.POSIXct(format(start(x),"%Y-%m-%d"))
timesteps <- seq(midnightDay1, end(x), by="30 min")
# 2) Make a copy of your object and set all values for Volume to 1
y <- x
y$Volume <- 1
# 3) Merge the copy with a zero-column xts object that has an index
# with all the values you want. Fill missing values with 0.
m <- merge(y, xts(,timesteps), fill=0)
# 4) Align all index values to 30-minute intervals
a <- align.time(m, 60*30)
# 5) Sum the values for Volume in each period
half_hour <- period.apply(a, endpoints(a, "minutes", 30), sum)
Upvotes: 3