Преобразование имен файлов в дату в году + недели возвращает ошибку в charToDate (x): строка символов не имеет стандартного однозначного формата

Для анализа временных рядов более 1000 растров в стеке растров мне нужна дата. Данные почти еженедельные в структуре файлов "...1981036....tif" Ноль разделяет год и неделю Мне нужно что-то вроде: "1981-36"

но всегда получаю ошибку Ошибка в charToDate (x): строка символов не имеет стандартного однозначного формата

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

приносит мне: 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"
…

Чтобы получить год и соответствующую неделю, я использовал следующий код:

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

приносит мне: график

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

Но мне нужно что-то вроде = "1981-35", чтобы иметь возможность построить свой временной ряд позже

Я пробовал это:

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

и получите ошибку: Ошибка в charToDate(x): строка символов не имеет стандартного однозначного формата

или я так пробовал

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

и получить ту же ошибку


person FranziM    schedule 05.04.2019    source источник
comment
проверьте это, возможно, это поможет вам [stackoverflow.com/questions/55007079/   -  person Andrei Niță    schedule 05.04.2019
comment
Должен ли я преобразовать разделительный ноль в -? Итак, с 1981035 по 1981-1935 гг.   -  person FranziM    schedule 05.04.2019


Ответы (2)


пока кто-нибудь не опубликует лучший способ сделать это, вы можете попробовать:

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")

Благодаря @Soren, который разместил этот ответ здесь: Получите месяц от неделя года

person Andrei Niță    schedule 05.04.2019
comment
большое спасибо Андрей, если я адаптирую и запущу ваш код, я получу много Н.А. в новые даты - person FranziM; 05.04.2019
comment
NA будет отображаться, если после нуля для разделения есть еще ноль, для 01 то, что за неделю 1 видит. Пример: 1982001 - person FranziM; 05.04.2019

Вы можете сделать это, если укажете, что понедельник является днем ​​недели 1 с %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"

В качестве альтернативы вы можете сделать то же самое, установив воскресенье как 0 с помощью %w.

person Oka    schedule 05.04.2019
comment
этот код работает очень хорошо этот код работает нормально до момента, когда as.character должен быть преобразован в as.date. На последнем шаге дата сохраняет характер класса вместо даты класса - person FranziM; 05.04.2019
comment
Если вам нужна переменная даты в качестве даты, вы можете сохранить переменную даты до окончательного форматирования (я добавил это в ответ) - person Oka; 05.04.2019
comment
Я добавил и переписал ваш код, для меня класс по-прежнему символ, а не дата - person FranziM; 05.04.2019
comment
Хм, в моем классе установки Дата перед format и символ после него. Были ли у вас какие-либо ошибки или предупреждения во время работы скрипта?? - person Oka; 05.04.2019
comment
так как мне нужен формат даты %Y-%U, я не могу не хранить ее в этом формате. Я не получаю сообщение об ошибке. Он сохраняет его как символ, потом я его конвертирую в дату, потом идет форматирование и это снова символ... - person FranziM; 05.04.2019
comment
Итак, у вас есть переменная date как класс Date в какой-то момент? - person Oka; 05.04.2019
comment
Я проверяю класс после каждого шага, но нет, у меня нет даты урока. Единственное, что я могу попробовать, это не использовать дату 1981-35, а фактическую дату одного из дней недели, например 1981-10-01. - person FranziM; 06.04.2019
comment
Так что, если вы скопируете код и запустите его, он не будет показывать дату урока в любой момент?? это странно - as.Date является базовой функцией и, похоже, не требует дополнительных пакетов или чего-то еще. - person Oka; 06.04.2019