Как найти самую высокую (самую последнюю) и самую низкую (самую раннюю) дату [R] - PullRequest
23 голосов
/ 08 декабря 2010

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

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

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

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

Мой фрейм данных выглядит так:

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

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

С уважением,

Ответы [ 2 ]

34 голосов
/ 08 декабря 2010

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

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), min(EntryTime)))
Time difference of 14 days

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

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

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

Цель 2: Вы, кажется, пытаетесь преобразовать фрейм данных в дату.Вы не можете сделать это.Что вы можете сделать, это переформатировать данные в компонентов фрейма данных.Здесь я добавляю столбцы к 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 ...
9 голосов
/ 19 мая 2014

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

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

    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"
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...