calculate mean daylength across a varying range of dates

how to calculate day length with latitude
astronomical twilight calculator
calculate sunrise sunset times excel
day length throughout the year
hours of daylight by latitude
sunrise, sunset calendar 2019
sunrise/sunset algorithm
bmnt calculator

I'm using the daylength function in the geosphere package to calculate day length at a location between two points. Depending on the specific individual and location, in the number of days over which I'm averaging day length varies.

While my function works when I hard code variables (i.e., provide a specific value for lat and date), it does not work when I supply a vector of values and get the following error and warning messages:

Error in mutate_impl(.data, dots) : Evaluation error: NA/NaN argument.
In addition: Warning messages:
1: In doy.prev:doy :
  numerical expression has 379 elements: only the first used
2: In doy.prev:doy :
  numerical expression has 379 elements: only the first used

I know this error pertains to my day length calculations because the other part of the code runs fine when it is omitted.

My code and a subset of data (i.e., first 25 observations):

df %>%
  mutate(mean.lat = if_else((ID == lag(ID) & site != lag(site)),
                          (lat + lag(lat))/2, NA_real_),
         doy.prev = if_else((ID == lag(ID) & 
                                site != lag(site)),
                             lag(yday(ts)), 
                             NA_real_),
         mean.day = if_else((ID == lag(ID) & 
                                site != lag(site) &
                                yday(ts) != yday(lag(ts)) & 
                                !is.na(mean.lat) & 
                                !is.na(doy.prev)),
                             mean(daylength(mean.lat, doy.prev:doy)), 
                             timeS))
dput(df)
structure(list(ID = structure(c(1L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 7L, 8L, 
8L), .Label = c("NB2014.12", "NB2014.13", "NB2014.14", "NB2014.15", 
"NB2014.16", "NB2014.42", "NB2014.43", "NB2014.44", "NB2014.45", 
"NB2014.47", "NB2014.48", "NB2014.49", "NB2014.70", "NB2014.71", 
"NB2014.72", "NB2014.73", "NB2014.74", "NB2014.75", "NB2014.76", 
"NB2014.77", "NB2014.78", "NB2014.79", "NB2014.80", "NB2014.81", 
"NB2015.156", "NB2015.157", "NB2015.158", "NB2015.159", "NB2015.160", 
"NB2015.312", "NB2015.313", "NB2015.314", "NB2015.315", "NB2015.316", 
"NB2015.317", "NB2015.318", "NB2015.320", "NB2015.321", "NB2015.322", 
"NB2015.323", "NB2015.324", "NB2015.325", "NB2015.326", "NB2015.327", 
"NB2015.328", "NB2015.329", "NB2015.330", "NB2015.331", "NB2015.332", 
"NB2015.333", "NB2015.334", "NB2015.335", "NB2015.336", "NB2015.337", 
"NB2015.338", "NB2015.339", "NB2015.340", "NB2015.341", "NB2015.342", 
"NB2015.343", "NB2015.344", "NB2015.345", "NB2015.346", "NB2015.347", 
"NB2015.348", "NB2015.349", "NB2015.350", "NB2015.351", "NB2018.10", 
"NB2018.11", "NB2018.12", "NB2018.13", "NB2018.14", "NB2018.15", 
"NB2018.16", "NB2018.17", "NB2018.18", "NB2018.19", "NB2018.20", 
"NB2018.21", "NB2018.22", "NB2018.23", "NB2018.24", "NB2018.25", 
"NB2018.26", "NB2018.27", "NB2018.28", "NB2018.29", "NB2018.30", 
"NB2018.31", "NB2018.32", "NB2018.33", "NB2018.34", "NB2018.35", 
"NB2018.37", "NB2018.38", "NB2018.39", "NB2018.40", "NB2018.41", 
"NB2018.42", "NB2018.43", "NB2018.44", "NB2018.45", "NB2018.46", 
"NB2018.47", "NB2018.48", "NB2018.49", "NB2018.5", "NB2018.50", 
"NB2018.51", "NB2018.52", "NB2018.53", "NB2018.54", "NB2018.55", 
"NB2018.56", "NB2018.57", "NB2018.58", "NB2018.59", "NB2018.6", 
"NB2018.60", "NB2018.61", "NB2018.62", "NB2018.63", "NB2018.64", 
"NB2018.7", "NB2018.8", "NB2018.9"), class = "factor"), site = c("Tantramar", 
"Tantramar", "HPWLR", "Tantramar", "Beaubassin", "Marsh Landings", 
"Eddie rd. ", "Marsh Landings", "Marsh Landings", "Marsh Landings", 
"Eddie rd. ", "Beaubassin", "AMHRST", "HPWLR", "Tantramar", "Tantramar", 
"Fork Field Farms", "WNERR", "GB_ferryway", "GB_thomas", "Tantramar", 
"HPWLR", "Tantramar", "Tantramar", "Marsh Landings"), lat = c(45.900303030303, 
45.900303030303, 45.83, 45.900303030303, 45.85, 45.85, 45.85, 
45.85, 45.85, 45.85, 45.85, 45.85, 45.79, 45.83, 45.900303030303, 
45.900303030303, 45.94, 43.34, 43.09, 43.08, 45.900303030303, 
45.83, 45.900303030303, 45.900303030303, 45.85), doy = c(213, 
206, 206, 217, 217, 217, 217, 217, 218, 218, 218, 218, 218, 218, 
194, 206, 207, 211, 211, 211, 220, 220, 207, 210, 210), ts = structure(c(1406899801.4133, 
1406297348.1112, 1406299522.4141, 1407276094.4158, 1407277417.7616, 
1407279028.1764, 1407279972.1813, 1407281880.08955, 1407285413.4387, 
1407314856.6032, 1407315906.52065, 1407316678.29125, 1407316887.28, 
1407319828.1424, 1405278154.7126, 1406330632.0613, 1406364501.8284, 
1406713079.0338, 1406716251.3933, 1406716449.5783, 1407490305.4993, 
1407491817.085, 1406370738.3239, 1406655731.0996, 1406673688.1819
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), timeS = c(NA, 
NA, 2174.30289983749, NA, 1323.34579992294, 1610.41479992867, 
944.004900217056, 1907.90824985504, NA, NA, 1049.91744995117, 
771.77060008049, 208.988749980927, 2940.86240005493, NA, NA, 
33869.7670998573, 348577.20539999, 3172.35950016975, 198.18499994278, 
NA, 1511.5857000351, NA, NA, 17957.0822999477)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -25L))

In plain R:

d <- data.frame(
    meanLat = c(45.0, 44.6),
    doy = c(207,211),
    doy.prev = 206:207
)
library(geosphere)
# one row
sum(daylength(d$meanLat[1], d$doy.prev[1]:d$doy[1]))
#[1] 29.96547
# all rows
apply(d, 1, function(x) sum(daylength(x[1], x[3]:x[2])))
#[1] 29.96547 74.25768

# you could also first make a proper long matrix
x <- do.call(rbind, apply(d, 1, function(x) cbind(x[1], x[3]:x[2])))
# followed by
tapply(daylength(x[,1], x[,2]), x[,1], sum)
#    44.6       45
#74.25768 29.96547 

Sunrise-Sunset.org, Check sunrise, sunset, dusk and dawn times for any location in the world! The time range during which the day becomes night or vice versa is called twilight. We can As you may have noticed, daylength or length of daytime varies over the year. The average day, a century ago, was 1.7 milliseconds shorter than today. Duration Between Two Dates – Calculates number of days. Time and Date Duration – Calculate duration, with both date and time included Birthday Calculator – Find when you are 1 billion seconds old

I added additional filter and it gave below warnings. Does it give any hint?

df %>%
  mutate(mean.lat = if_else((ID == lag(ID) & site != lag(site)),
                            (lat + lag(lat))/2, NA_real_),
         doy.prev = if_else((ID == lag(ID) & 
                               site != lag(site)),
                            lag(yday(ts)), 
                            NA_real_)) %>%
  filter(!is.na(doy.prev)) %>%
  mutate(mean.day = if_else(((ID == lag(ID) & 
                               site != lag(site) &
                               yday(ts) != yday(lag(ts))) & 
                               !is.na(mean.lat) & 
                               !is.na(doy.prev)),
                            mean(daylength(mean.lat, doy.prev:doy)), 
                            timeS)) 
12 NB2014.16 GB_ferryway       43.1   211 2014-07-30 10:30:51   3172.     43.2      211   3172. 
13 NB2014.16 GB_thomas         43.1   211 2014-07-30 10:34:09    198.     43.1      211    198. 
14 NB2014.42 HPWLR             45.8   220 2014-08-08 09:56:57   1512.     45.9      220   1512. 
15 NB2014.44 Marsh Landings    45.8   210 2014-07-29 22:41:28  17957.     45.9      210  17957. 
Warning messages:
1: In doy.prev:doy :
  numerical expression has 15 elements: only the first used
2: In doy.prev:doy :
  numerical expression has 15 elements: only the first used

NOAA Improved Sunrise/Sunset Calculation, To perform calculations for a different date, simply select a month in the pull down menu, and enter the day and four digit year in the appropriate input boxes. When � The Duration Calculator calculates the number of days, months and years between two dates.

I was unable to find a way to get the daylength function to work within dplyr. However, here is a work-around:

df2 <- df %>%
    filter(!is.na(meanLat))

df2$timeHday = apply((df2 %>% select(meanLat, doy.local, doy.prev1)), 
                   1,
                   function(x) sum(daylength(x[1], x[3]:x[2])))

df <- df %>% left_join(df2, by = c("ID", "ts.mn"))

Many thanks to Robert Hijmans for the assistance!

Day length fluctuations, The length of the day, which has increased over the long term of Earth's history due to tidal effects, is also subject to fluctuations on a shorter scale of time. Exact measurements of time by atomic clocks and satellite laser ranging have revealed that the length of day (LOD) is subject to a number of different These subtle variations have periods that range from a few weeks to a few� I would like to calculate the pairwise average and median number of days between multiple date variables. My raw data df might look as following:. id invitation account_date first_order second_order third_order 1 1/1/2016 1/7/2016 1/20/2016 1/22/2016 NA 2 1/1/2016 1/8/2016 1/22/2016 1/23/2016 1/25/2016 3 1/1/2016 1/5/2016 1/20/2016 2/1/2016 NA 4 1/1/2016 1/2/2016 1/18/2016 2/4/2016 2/6/2016

Sunrise and Sunset Calculator, Length of day; When dawn will break and when darkness will descend. To see this information for a date other than today, simply change the date to the� Free date calculator computes the difference between two dates. It can also add to or subtract from a date. Both calculators can deal with business days and holidays. Learn more about the most common calendar system used today, or explore hundreds of other calculators addressing finance, math, fitness, health, and more.

Relative day lengths, On December 21, the shortest day of the year, the day length ranges from almost 11 revolution on its axis. one year equals one complete orbit around the sun. South of the equator, in the southern hemisphere, you'll find Hamilton, Australia. is to show that day length, or number of hours of daylight, varies dramatically� Sometimes, the range is dynamic based on the criteria users input. In this case, you can calculate the average of dynamic range as below steps. 1. Batch define names for each row and each column in the specified range.

DATESBETWEEN function (DAX), Use it to filter an expression by a custom date range. The following Sales table measure definition uses the DATESBETWEEN function to Life-to-date represents the accumulation of a measure over time since the very� Calculate average between two dates with formulas. For example, I have the following data range, and now I need to average the numbers in column B between 11/01/2016 and 03/01/2017 of column A. To get the average between two given dates, please apply the following array formula:

Comments
  • What value do you expect doy.prev to have instead of NA, since daylength will give that error if doy contains NA?
  • @Sonny if doy = NA, then I don't need the daylength calculation. that's why I added !is.na(doy.prev) to the if_else statement.
  • But you have used & condition , so it will ignore those lines where not all are NA.
  • Sorry @Sonny, I'm not following your point. To me !is.na(doy.prev) means do not include any values where doy.prev = NA.
  • Unfortunately, no that doesn't make much sense to me. I don't want to include the filter because I need all the data for a later calculation. Also, without the previous rows, it's hard for me to confirm that the code is doing what I want it to. Based on my full spreadsheet the first two lines are definitely wrong because the individual was observed twice on the same day. I only need to calculate daylength when consecutive observations for the same individual (ID == lag(ID)), are for two different locations (site != lag(site)) on two different days (yday(ts) != lag(yday(ts)).
  • When I substitute in an innocuous value for the daylength function, like 100, I see that the only individuals that should get a day length calculation (in the first 25 rows) are rows 17 and 18 (NB2014.16 at WNERR and GB_ferryway).