Подтвердить что ты не робот

Как найти самую высокую (самую последнюю) и самую низкую (самую раннюю) дату [R]

Я пытаюсь преобразовать два столбца в моем ядре данных в "хороший класс даты и времени", и до сих пор не имел большого успеха с ним. Ive пробовал различные классы (timeDate, Date, timeSeries, POSIXct, POSIXlt), но безуспешно. Возможно, я просто упускаю из виду очевидное и потому, что Ive пытался так много подходов, я просто не знаю, что больше. Я надеюсь, что некоторые из вас могут пролить свет на то, где я ошибаюсь.

Цель: Я хочу рассчитать разницу между двумя датами, используя самую раннюю и последнюю дату. Я получил эту работу с head() и tail(), но поскольку эти значения необходимы для самой ранней и последней даты в моих данных, мне нужен другой способ. (Я не могу сортировать данные для работы, потому что он сортирует данные только в день даты.)

Вторая цель. Я хочу конвертировать даты из ежедневного формата (т.е. 8-12-2010) в еженедельные, ежемесячные и годовые уровни (например, "49 -2010", "декабрь-10" ', а всего лишь' 2010 '). Это можно сделать с настройками формата (например, "% d-% m-% y" ). Может ли это быть сделано с преобразованием data.frame в класс времени, а затем преобразование timeclass в правильном формате (8-12-2010 → format ( "% B-% y" ) → 'декабрь-10'), а затем преобразование этого временного класса в фактор с уровнями за каждый месяц?

Для обеих целей мне нужно каким-то образом преобразовать фреймворк даты в класс времени, и именно здесь я столкнулся с некоторыми трудностями.

Мой dataframe выглядит так:

> tradesList[c(1,10,11,20),14:15] -> tmpTimes4
> tmpTimes4
   EntryTime ExitTime
1   01-03-07 10-04-07
10  29-10-07 02-11-07
11  13-04-07 14-05-07
20  18-12-07 20-02-08

Вот что я пробовал:

> class(tmpTimes4)
[1] "data.frame"
> as.Date(head(tmpTimes4$EntryTimes, n=1), format="%d-%m-%y")
Error in as.Date.default(head(tmpTimes4$EntryTimes, n = 1), format = "%d-%m-%y") : 
  do not know how to convert 'head(tmpTimes4$EntryTimes, n = 1)' to class "Date"
> as.timeDate(tmpTimes4, format="%d-%m-%y")
Error in as.timeDate(tmpTimes4, format = "%d-%m-%y") : 
  unused argument(s) (format = "%d-%m-%y")
> timeSeries(tmpTimes4, format="%d-%m-%y")
Error in midnightStandard2(charvec, format) : 
  'charvec' has non-NA entries of different number of characters
> tmpEntryTimes4 <- timeSeries(tmpTimes4$EntryTime, format="%d-%m-%y")
> tmpExitTimes4 <- timeSeries(tmpTimes4$ExitTime, format="%d-%m-%y")
> tmpTimes5 <- cbind(tmpEntryTimes4,tmpExitTimes4)
> colnames(tmpTimes5) <- c("Entry","Exit")
> tmpTimes5
     Entry    Exit    
[1,] 01-03-07 10-04-07
[2,] 29-10-07 02-11-07
[3,] 13-04-07 14-05-07
[4,] 18-12-07 20-02-08
> class(tmpTimes5)
[1] "timeSeries"
attr(,"package")
[1] "timeSeries"
> as.timeDate(tmpTimes5, format="%d-%m-%y")
Error in as.timeDate(tmpTimes5, format = "%d-%m-%y") : 
  unused argument(s) (format = "%d-%m-%y")
> as.Date(tmpTimes5, format="%d-%m-%y")
Error in as.Date.default(tmpTimes5, format = "%d-%m-%y") : 
  do not know how to convert 'tmpTimes5' to class "Date"
> format.POSIXlt(tmpTimes5, format="%d-%m-%y", usetz=FALSE)
Error in format.POSIXlt(tmpTimes5, format = "%d-%m-%y", usetz = FALSE) : 
  wrong class
> as.POSIXlt(tmpTimes5, format="%d-%m-%y", usetz=FALSE)
Error in as.POSIXlt.default(tmpTimes5, format = "%d-%m-%y", usetz = FALSE) : 
  do not know how to convert 'tmpTimes5' to class "POSIXlt"
> as.POSIXct(tmpTimes5, format="%d-%m-%y", usetz=FALSE)
Error in as.POSIXlt.default(x, tz, ...) : 
  do not know how to convert 'x' to class "POSIXlt"

У пакетов TimeDate есть функция для диапазона, однако преобразование в класс Date работает для отдельного экземпляра, но по какой-то причине не для фрейма данных:

> as.Date(tmpTimes4[1,1], format="%d-%m-%y")
[1] "2007-03-01"
> as.Date(tmpTimes4, format="%d-%m-%y")
Error in as.Date.default(tmpTimes4, format = "%d-%m-%y") : 
  do not know how to convert 'tmpTimes4' to class "Date"

В этот момент я почти верю, что это невозможно сделать, поэтому любые мысли будут высоко оценены!

Привет,

4b9b3361

Ответ 1

Начните с некоторых фиктивных данных:

start <- as.Date("2010/01/01")
end <- as.Date("2010/12/31")
set.seed(1)
datewant <- seq(start, end, by = "days")[sample(15)]
tmpTimes <- data.frame(EntryTime = datewant, 
                       ExitTime = datewant + sample(100, 15))
## reorder on EntryTime so in random order
tmpTimes <- tmpTimes[sample(NROW(tmpTimes)), ]
head(tmpTimes)

поэтому у нас есть что-то вроде этого:

> head(tmpTimes)
    EntryTime   ExitTime
8  2010-01-14 2010-03-16
9  2010-01-05 2010-01-17
7  2010-01-10 2010-01-30
3  2010-01-08 2010-04-16
10 2010-01-01 2010-01-26
13 2010-01-12 2010-02-15

Используя вышеизложенное, посмотрите Цель 1, вычислите разницу между самой ранней и последней датой. Вы можете обрабатывать даты так, как если бы они были номерами (так они хранятся внутри страны в любом случае), поэтому функции, такие как min() и max(), будут работать. Вы можете использовать функцию difftime():

> with(tmpTimes, difftime(max(EntryTime), main(EntryTime)))
Time difference of 14 days

или используйте стандартное вычитание

> with(tmpTimes, max(EntryTime) - min(EntryTime))
Time difference of 14 days

чтобы получить разницу в днях. head() и tail() будут работать, только если сортировать даты, поскольку они принимают первое и последнее значение в векторе, а не самое высокое и самое низкое фактическое значение.

Цель 2: Кажется, вы пытаетесь преобразовать фрейм данных в Date. Вы не можете этого сделать. Что вы можете сделать, это переформатировать данные в компонентах фрейма данных. Здесь я добавляю столбцы в tmpTimes путем переформатирования столбца EntryTime в несколько разных сводок даты.

tmpTimes2 <- within(tmpTimes, weekOfYear <- format(EntryTime, format = "%W-%Y"))
tmpTimes2 <- within(tmpTimes2, monthYear <- format(EntryTime, format = "%B-%Y"))
tmpTimes2 <- within(tmpTimes2, Year <- format(EntryTime, format = "%Y"))

Дарение:

> head(tmpTimes2)
    EntryTime   ExitTime weekOfYear    monthYear Year
8  2010-01-14 2010-03-16    02-2010 January-2010 2010
9  2010-01-05 2010-01-17    01-2010 January-2010 2010
7  2010-01-10 2010-01-30    01-2010 January-2010 2010
3  2010-01-08 2010-04-16    01-2010 January-2010 2010
10 2010-01-01 2010-01-26    00-2010 January-2010 2010
13 2010-01-12 2010-02-15    02-2010 January-2010 2010

Если вы являетесь американцем или хотите использовать конвенцию США на начало недели (%W начинает неделю в понедельник, в США соглашение начинается в воскресенье), измените %W на %U. ?strftime имеет более подробную информацию о том, что представляют %W и %U.


Конечная точка в формате данных: В приведенном выше примере я работал с датами в стандартном формате R. У вас есть данные, хранящиеся в кадре данных, в нестандартной разметке, предположительно как символы или факторы. Итак, у вас есть что-то вроде:

tmpTimes3 <- within(tmpTimes, 
                    EntryTime <- format(EntryTime, format = "%d-%m-%y"))
tmpTimes3 <- within(tmpTimes3, 
                    ExitTime <- format(ExitTime, format = "%d-%m-%y"))

> head(tmpTimes3)
   EntryTime ExitTime
8   14-01-10 16-03-10
9   05-01-10 17-01-10
7   10-01-10 30-01-10
3   08-01-10 16-04-10
10  01-01-10 26-01-10
13  12-01-10 15-02-10

Вам нужно преобразовать эти символы или факторы в то, что R понимает как дату. Мое предпочтение было бы классом "Date". Перед тем, как вы попробуете приведенные выше ответы с вашими данными, преобразуйте данные в правильный формат:

tmpTimes3 <- 
    within(tmpTimes3, {
           EntryTime <- as.Date(as.character(EntryTime), format = "%d-%m-%y")
           ExitTime <- as.Date(as.character(ExitTime), format = "%d-%m-%y")
           })

чтобы ваши данные выглядели следующим образом:

> head(tmpTimes3)
    EntryTime   ExitTime
8  2010-01-14 2010-03-16
9  2010-01-05 2010-01-17
7  2010-01-10 2010-01-30
3  2010-01-08 2010-04-16
10 2010-01-01 2010-01-26
13 2010-01-12 2010-02-15
> str(tmpTimes3)
'data.frame':   15 obs. of  2 variables:
 $ EntryTime:Class 'Date'  num [1:15] 14623 14614 14619 14617 14610 ...
 $ ExitTime :Class 'Date'  num [1:15] 14684 14626 14639 14715 14635 ...

Ответ 2

Короткий ответ:

  • Преобразовать на дату, если это еще не сделано.
  • Затем используйте min и max в списке дат.

    date_list = structure(c(15401, 15405, 15405), class = "Date")
    date_list
    #[1] "2012-03-02" "2012-03-06" "2012-03-06"
    
    min(date_list)
    #[1] "2012-03-02"
    max(date_list)
    #[1] "2012-03-06"