The goal of timefully is to make it straightforward
to reshape, re-timezone and visualise regularly spaced energy time
series. This tutorial walks through the core workflow using the
package’s bundled data frame timefully::dtf.
Explore the sample data
dtf contains a full year of quarter-hour values recorded
in the Europe/Amsterdam timezone during
2023. We start by zooming into one week so plots stay
compact.
week_amsterdam <- timefully::dtf |>
filter(datetime >= as.POSIXct("2023-06-01 00:00:00", tz = "Europe/Amsterdam"),
datetime < as.POSIXct("2023-06-08 00:00:00", tz = "Europe/Amsterdam"))
glimpse(week_amsterdam)
#> Rows: 672
#> Columns: 3
#> $ datetime <dttm> 2023-06-01 00:00:00, 2023-06-01 00:15:00, 2023-06-01 00:30:0…
#> $ solar <dbl> 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000…
#> $ building <dbl> 1.836046, 1.746280, 1.656513, 1.566747, 1.476981, 1.452224, 1…The helper plot_ts() produces an interactive dygraph so
we can inspect the raw values.
plot_ts(week_amsterdam, ylab = "kW", legend_show = "always",
title = "Quarter-hour readings (Europe/Amsterdam)")Change the time resolution
To produce hourly averages we call
change_timeseries_resolution() with the desired resolution
(in minutes) and the aggregation method. The first column remains a
datetime column and the numeric columns are summarised accordingly.
week_hourly <- change_timeseries_resolution(
week_amsterdam,
resolution = 60,
method = "average"
)
plot_ts(week_hourly, ylab = "kW", legend_show = "always",
title = "Hourly averages")Convert to a different timezone
If the data should be reported in another timezone, but keeping the
same date range, we can use function
change_timeseries_tzone():
week_paris <- change_timeseries_tzone(week_amsterdam, tzone = "America/Los_Angeles")
tz(week_amsterdam$datetime[1])
#> [1] "Europe/Amsterdam"
tz(week_paris$datetime[1])
#> [1] "America/Los_Angeles"
plot_ts(week_paris, ylab = "kW", legend_show = "always")Note that the data points are moved in time to reflect the new
timezone, so the daily patterns shift accordingly. This is used to
preserve the local time context of the data. If you want to keep the
same clock times but just change the timezone label, use
lubridate::force_tz() instead.
Adapt to a new date range
Finally, adapt_timeseries() lets us change both the date
range and the timezone in one step. Here we request ten days of Paris
time starting on 1 June 2025. The function fills any missing slots using
the most recent data with the same weekday and time of day, falling back
to fill_from_past() when necessary.
adapted_paris <- adapt_timeseries(
timefully::dtf,
start_date = as.Date("2025-06-01"),
end_date = as.Date("2025-06-10"),
tzone = "Europe/Paris",
fill_gaps = TRUE
)
plot_ts(adapted_paris, ylab = "kW", legend_show = "always",
title = "Adapted time series (1–10 June 2025)")These building blocks can be combined with the rest of the package to prepare clean, timezone-aware time series ready for analysis or reporting.
