admin管理员组

文章数量:1312662

I would like to add columns with sunrise and sunset times for each row of data, each row having a different date and different location. The data frame looks like this but with 1500 rows:

df1 <- data.frame(
ID = c(1, 2, 3, 4), 
date = as.Date(c('2020-09-1', '2020-09-15', '2021-10-05', '2024-08-31')), 
latitude = c(47.555, 46.123, 46.892, 47.598), 
longitude = c(-50.123, -50.456, -50.789, -50.147)
)

I only know how to get sunrise and sunset time for a list of days with a fixed location as below:

night <- as.data.frame(suncalc::getSunlightTimes(date = list_days,  
                                        lat = y, lon = x,
                                        keep = c('sunrise','sunset'),
                                        tz="America/St_Johns"))

I am guessing I need to reiterate the function getSunLightTimes for each row of data but I am not sure how to code this...

Thank you for your help!

I would like to add columns with sunrise and sunset times for each row of data, each row having a different date and different location. The data frame looks like this but with 1500 rows:

df1 <- data.frame(
ID = c(1, 2, 3, 4), 
date = as.Date(c('2020-09-1', '2020-09-15', '2021-10-05', '2024-08-31')), 
latitude = c(47.555, 46.123, 46.892, 47.598), 
longitude = c(-50.123, -50.456, -50.789, -50.147)
)

I only know how to get sunrise and sunset time for a list of days with a fixed location as below:

night <- as.data.frame(suncalc::getSunlightTimes(date = list_days,  
                                        lat = y, lon = x,
                                        keep = c('sunrise','sunset'),
                                        tz="America/St_Johns"))

I am guessing I need to reiterate the function getSunLightTimes for each row of data but I am not sure how to code this...

Thank you for your help!

Share Improve this question asked Jan 31 at 14:26 FionaFiona 213 bronze badges 1
  • 1 Sadly, the lat and lon parameters of getSunlightTimes aren't vectorised. So lapply would help. Or, since you have a data.frame, group_by (or rowwise) and group_modify from the tidyverse would also do the trick. Since the date parameter is vectorised, there might be a performance gain to be had by first sorting by lat and lon (and then later reverting to the original row order if necessary)... – Limey Commented Jan 31 at 14:31
Add a comment  | 

2 Answers 2

Reset to default 3

getSunlightTimes() can also be called with a data.frame with date, lat & lon columns.

To approach this with dplyr in a single mutate() call, you could prepare a local frame with correctly named columns with tibble() and then select required columns from getSunlightTimes() output; returned 2-column frame gets automatically unpacked to 2 columns in parent frame:

library(suncalc)
library(dplyr)

df1 <- data.frame(
  ID = c(1, 2, 3, 4), 
  date = as.Date(c('2020-09-1', '2020-09-15', '2021-10-05', '2024-08-31')), 
  latitude = c(47.555, 46.123, 46.892, 47.598), 
  longitude = c(-50.123, -50.456, -50.789, -50.147)
)

df1 |> 
  mutate(
    tibble(date, lat = latitude, lon = longitude) |> 
      getSunlightTimes(data = _, keep = c('sunrise', 'sunset'), tz="America/St_Johns") |> 
      select(sunrise, sunset)
  )
#>   ID       date latitude longitude             sunrise              sunset
#> 1  1 2020-09-01   47.555   -50.123 2020-09-01 06:11:05 2020-09-01 19:32:41
#> 2  2 2020-09-15   46.123   -50.456 2020-09-15 06:31:44 2020-09-15 19:04:52
#> 3  3 2021-10-05   46.892   -50.789 2021-10-05 06:58:32 2021-10-05 18:26:51
#> 4  4 2024-08-31   47.598   -50.147 2024-08-31 06:09:44 2024-08-31 19:34:53

Created on 2025-01-31 with reprex v2.1.1

Using R base, You may try this:

t(sapply(1:nrow(df1),
  function(i){
    suncalc::getSunlightTimes(date = df1$date[i],
                              lat = df1$latitude[i],
                              lon = df1$longitude[i],
                              keep = c('sunrise','sunset'),
                              tz="America/St_Johns")

本文标签: rGet sunrise and sunset times for multiple locations and datesStack Overflow