1

For a time series analysis of over 1000 raster in a raster stack I need the date. The data is almost weekly in the structure of the files "... 1981036 .... tif" The zero separates year and week I need something like: "1981-36"

but always get the error Error in charToDate (x): character string is not in a standard unambiguous format

library(sp)
library(lubridate)
library(raster)
library(Zoo)

raster_path <- ".../AVHRR_All"
all_raster <- list.files(raster_path,full.names = TRUE,pattern = ".tif$")
all_raster

brings me: all_raster

".../VHP.G04.C07.NC.P1981036.SM.SMN.Andes.tif"
".../VHP.G04.C07.NC.P1981037.SM.SMN.Andes.tif"
".../VHP.G04.C07.NC.P1981038.SM.SMN.Andes.tif"
…

To get the year and the associated week, I have used the following code:

timeline <- data.frame(
  year= as.numeric(substr(basename(all_raster), start = 17, stop = 17+3)),
  week= as.numeric(substr(basename(all_raster), 21, 21+2))
)
timeline

brings me: timeline

     year week
1    1981   35
2    1981   36
3    1981   37
4    1981   38
…

But I need something like = "1981-35" to be able to plot my time series later

I tried that:

timeline$week <- as.Date(paste0(timeline$year, "%Y")) + week(timeline$week -1, "%U")

and get the error:Error in charToDate(x) : character string is not in a standard unambiguous format

or I tried that

fileDates <- as.POSIXct(substr((all_raster),17,23), format="%y0%U")

and get the same error

FranziM
  • 11
  • 2

2 Answers2

0

until someone will post a better way to do this, you could try:

x <- c(".../VHP.G04.C07.NC.P1981036.SM.SMN.Andes.tif", ".../VHP.G04.C07.NC.P1981037.SM.SMN.Andes.tif",
       ".../VHP.G04.C07.NC.P1981038.SM.SMN.Andes.tif")

xx <- substr(x, 21, 27)


library(lubridate)


dates <- strsplit(xx,"0")
dates <- sapply(dates,function(x) {
  year_week <- unlist(x)
  year <- year_week[1]
  week <- year_week[2]
  start_date <- as.Date(paste0(year,'-01-01'))
  date <- start_date+weeks(week)
  #note here: OP asked for beginning of week.  
  #There's some ambiguity here, the above is end-of-week; 
  #uncommment here for beginning of week, just subtracted 6 days.  
  #I think this might yield inconsistent results, especially year-boundaries
  #hence suggestion to use end of week.  See below for possible solution
  #date <- start_date+weeks(week)-days(6)

  return (as.character(date))
})


newdates <- as.POSIXct(dates)
format(newdates, "%Y-%W")

Thanks to @Soren who posted this anwer here: Get the month from the week of the year

Andrei Niță
  • 517
  • 1
  • 3
  • 14
  • thank you very much Andrei, if I adapt and run your code, I get many "NA" into "newdates" – FranziM Apr 05 '19 at 11:15
  • NA will be displayed if there is still a zero after the zero for separating, for 01 what for the week 1 sees. Example: "1982001" – FranziM Apr 05 '19 at 11:23
0

You can do it if you specify that Monday is a Weekday 1 with %u:

w <- c(35,36,37,38)
y <- c(1981,1981,1981,1981)
s <- c(1,1,1,1)
df <- data.frame(y,w,s)
df$d <- paste(as.character(df$y), as.character(df$w),as.character(df$s), sep=".")
df$date <- as.Date(df$d, "%Y.%U.%u")

# So here we have variable date as date if you need that for later. 
class(df$date)
#[1] "Date"

# If you want it to look like Y-W, you can do the final formatting:
df$date <- format(df$date, "%Y-%U")

#     y  w s         d    date
# 1 1981 35 1 1981.35.1 1981-35
# 2 1981 36 1 1981.36.1 1981-36
# 3 1981 37 1 1981.37.1 1981-37
# 4 1981 38 1 1981.38.1 1981-38

# NB: though it looks correct, the resulting df$date is actually a character: 
class(df$date)
#[1] "character"

Alternatively, you could do the same by setting the Sunday as 0 with %w.

Oka
  • 1,318
  • 6
  • 11
  • this code works very well this code works fine until the point where the as.character is to be converted to an as.date. In the last step "date" retains the class "character" instead of the class "date" – FranziM Apr 05 '19 at 12:11
  • If you need the date variable as date, you can keep the date variable before the final formatting (I added that to the answer) – Oka Apr 05 '19 at 12:38
  • I have added and rewritten your code, for me the class is still character instead of date – FranziM Apr 05 '19 at 13:00
  • Hmm, on my setup class is "Date" before the `format`, and "character" after it. Did you get any errors or warnings during the script?? – Oka Apr 05 '19 at 13:12
  • since I need the date format %Y-% U, I can not avoid storing it in this format. I do not get an error message. He saves it as a character, then I convert it to date, then comes the formatting and it's again a character ... – FranziM Apr 05 '19 at 13:22
  • Ok, so you do have the variable date as class "Date" at some point? – Oka Apr 05 '19 at 13:29
  • I check the class after every step, but no, I havn't the class date. The only thing I can try, is not to use the date 1981-35 but the actual date of one of the weekdays, such as the 1981-10-01 – FranziM Apr 06 '19 at 12:55
  • So if you copy-paste the code and run it, it will not show class date at any point?? that´s weird - `as.Date` is a base function and doesn´t seem to require extra packages or anything.. – Oka Apr 06 '19 at 15:48