Jour julien à jour

Sep 19 2020

J'ai une base de données avec une colonne pour l'année et une autre colonne en jour julien (1-366, 1-365 selon l'année). Je voulais savoir comment définir efficacement la colonne DOY_start comme Date en fonction de l'année (pour tenir compte des années bissextiles).

J'ai essayé d'utiliser as.Date (), as.POSIXct (), lubridate :: as_date ()

Mais j'ai échoué dans toutes mes épreuves. Vous trouverez ci-dessous un exemple de code avec des données générées qui sont vraiment similaires à celles d'origine.

Merci beaucoup pour tout conseil.

library(tibble)

Year <- 1980:2020
DOY_start <- as.integer(rnorm(length(Year), mean=91.1, sd=9.65))
var <- cbind(Year, DOY_start)

var <- as_tibble(var) 
head(var)
#> # A tibble: 6 x 2
#>    Year DOY_start
#>   <int>     <int>
#> 1  1980        98
#> 2  1981        89
#> 3  1982        79
#> 4  1983        97
#> 5  1984        81
#> 6  1985        80

var$DOY_start_date <- as.POSIXct(strptime(var$DOY_start, "%j"))

head(var)
#> # A tibble: 6 x 3
#>    Year DOY_start DOY_start_date     
#>   <int>     <int> <dttm>             
#> 1  1980        98 2020-04-07 00:00:00
#> 2  1981        89 2020-03-29 00:00:00
#> 3  1982        79 2020-03-19 00:00:00
#> 4  1983        97 2020-04-06 00:00:00
#> 5  1984        81 2020-03-21 00:00:00
#> 6  1985        80 2020-03-20 00:00:00

Créé le 2020-09-18 par le package reprex (v0.3.0)

Réponses

3 DirkEddelbuettel Sep 19 2020 at 05:55

C'est un puzzle intéressant. Nous savons qu'il as.POSIXltcontient le numéro du jour de l'année et que certaines bibliothèques de dates s'y convertissent, mais je n'ai pas pu trouver immédiatement un analyseur qui s'en occupe.

Là encore, l'arithmentique des dates est tout ce dont nous avons besoin. Nous obtenons toujours la date du 1er janvier. Et la date souhaitée est alors simplement le 1er janvier plus le nombre du «jour de l'année» moins 1.

Code
yearyearday <- function(yr, yd) {
    base <- as.Date(paste0(yr, "-01-01")) # take Jan 1 of year
    day <- base + yd - 1
}

set.seed(42)  # make it reproducible
sample <- data.frame(year=1980:2020, doy=as.integer(rnorm(41,mean=91.1,sd=9.65)))

sample$date <- yearyearday(sample$year, sample$doy)

head(sample)
Production
R> yearyearday <- function(yr, yd) {
+     base <- as.Date(paste0(yr, "-01-01")) # take Jan 1 of year
+     day <- base + yd - 1
+ }
R> 
R> set.seed(42)  # make it reproducible
R> sample <- data.frame(year=1980:2020, 
+                       doy=as.integer(rnorm(41, mean=91.1, sd=9.65)))
R> 
R> sample$date <- yearyearday(sample$year, sample$doy)
R> 
R> head(sample)
  year doy       date
1 1980 104 1980-04-13
2 1981  85 1981-03-26
3 1982  94 1982-04-04
4 1983  97 1983-04-07
5 1984  95 1984-04-04
6 1985  90 1985-03-31
R> 

Comme souvent avec le calcul de la date, rien en plus de la base R n'est nécessaire.