web-dev-qa-db-fra.com

Comment trouver la date la plus élevée (la plus récente) et la plus basse (la plus ancienne) [R]

J'essaie de transformer deux colonnes de ma trame de données en "bonne" classe de date et d'heure, et jusqu'à présent, je n'ai pas eu beaucoup de succès. J'ai essayé différentes classes (timeDate, Date, timeSeries, POSIXct, POSIXlt) mais sans succès. Peut-être que je néglige juste l'évidence et parce que j'ai essayé tellement d'approches que je ne sais plus quoi. J'espère que certains d'entre vous pourront éclairer où je me trompe.

Objectif: Je veux calculer la différence entre deux dates en utilisant la première et la dernière date. Je l'ai fait fonctionner avec head() et tail(), mais parce que ces valeurs ne sont pas nécessaires la date la plus ancienne et la plus récente dans mes données, j'ai besoin d'une autre méthode. (Je n'arrive pas à faire fonctionner le tri des données, car il trie les données uniquement le jour de la date.)

Deuxième objectif: Je souhaite convertir les dates du format quotidien (c.-à-d. 8-12-2010) en niveaux hebdomadaires, mensuels et annuels (c.-à-d. '49 -2010 ',' décembre-10 'et juste '2010'). Cela peut être fait avec les paramètres de format (comme %d-%m-%y). Cela peut-il être fait en convertissant data.frame en une classe horaire et en transformant la classe temporelle au bon format (8-12-2010 -> format("%B-%y") -> 'december-10'), puis transformer cette classe horaire en un facteur avec des niveaux pour chaque mois?

Pour les deux objectifs, j'ai besoin de convertir le cadre de date d'une manière ou d'une autre en classe de temps, et c'est là que j'ai rencontré des difficultés.

Mon dataframe ressemble à ceci:

> 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

Voici un résumé de ce que j'ai essayé:

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

Les packages TimeDate ont une fonction pour "plage", cependant, la conversion en classe Date fonctionne pour une instance individuelle, mais pour une raison quelconque, pas pour une trame de données:

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

À ce stade, je crois presque que c'est impossible à faire, donc toutes les pensées seraient très appréciées!

Cordialement,

25
Jura

Commencez avec des données factices:

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)

nous avons donc quelque chose comme ça:

> 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

En utilisant ce qui précède, regardez Objectif 1, calculez la différence entre la première et la dernière date. Vous pouvez traiter les dates comme s'il s'agissait de nombres (c'est de cette façon qu'elles sont stockées en interne de toute façon), donc les fonctions comme min() et max() fonctionneront. Vous pouvez utiliser la fonction difftime():

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

ou utilisez une soustraction standard

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

pour faire la différence en jours. head() et tail() ne fonctionneront que si vous triez les dates car elles prennent la première et la dernière valeur dans un vecteur, pas la valeur réelle la plus élevée et la plus basse.

Objectif 2: Vous semblez essayer de convertir un bloc de données en une date. Tu ne peux pas faire ça. Ce que vous pouvez faire est de reformater les données dans les composants de la trame de données. Ici, j'ajoute des colonnes à tmpTimes en reformatant la colonne EntryTime en plusieurs résumés différents de la date.

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

Donnant:

> 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

Si vous êtes américain ou souhaitez utiliser la convention américaine pour le début de la semaine (%W Commence la semaine un lundi, dans la convention américaine commence un dimanche), modifiez le %W à %U. ?strftime Contient plus de détails sur ce que %W Et %U Représentent.


n dernier point sur le format des données: Dans ce qui précède, j'ai travaillé avec des dates au format R standard. Vos données sont stockées dans une trame de données dans un balisage non standard, probablement sous forme de caractères ou de facteurs. Vous avez donc quelque chose comme:

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

Vous devez convertir ces caractères ou facteurs en quelque chose que R comprend comme une date. Ma préférence serait la classe "Date". Avant d'essayer les réponses ci-dessus avec vos données, convertissez vos données au format correct:

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

afin que vos données ressemblent à ceci:

> 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 ...
35
Gavin Simpson

Réponse courte:

  • Convertissez à ce jour si ce n'est déjà fait.
  • Utilisez ensuite min et max sur la liste des dates.

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