Jour julien à jour
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
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.
Codeyearyearday <- 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.