2010-11-30 17 views
10

Je suis relativement nouveau à R, mais c'est la première fois que j'ai affaire à des conversions de date. J'ai lu dans mes données d'un CSV (en utilisant read.table()), mais j'ai court-circuité les données pour mettre en évidence mon problème. Lorsqu'il est lu dans R, le champ Date est un caractère.Convertir un caractère en Date dans R

Simplement, la plupart de mes dates sont coercées correctement, sauf dans quelques cas. L'exemple ci-dessous vous montrera, espérons-le, ce qui se passe.

# my attempt to coerce the date -- uses the stringr package 
prods.all$Date2 <- as.Date(str_sub(prods.all$Date, 1, 
       str_locate(prods.all$Date, " ")[1]-1), 
       "%m/%d/%Y") 

# grab two rows to highlight my issue 
temp <- prods.all[c(1925:1926), c(1,8)] 

> temp 
        Date  Date2 
1925 10/9/2009 0:00:00 2009-10-09 
1926 10/15/2009 0:00:00 0200-10-15 

Comme vous pouvez le voir, l'année de certaines des dates est inexacte. Le modèle semble se produire lorsque le jour est à deux chiffres. J'ai regardé quelques livres et j'ai essayé Google d'une meilleure façon, mais tout semble indiquer que mes données ne sont pas formatées correctement en entrée. Étant donné la puissance de R, je me rends compte qu'il est très facile de forcer la colonne à être valide et que je néglige une solution évidente.

Toute aide que vous pouvez fournir sera grandement appréciée.

+0

La raison pour laquelle vous obtenez l'invalide 0200 date est que les longueurs de caractères de la journée sont différentes (deux chiffres pour 15 oct, un chiffre pour 9 oct) - et votre code de substitution de chaîne ne tient pas compte de cela. En tout cas, vous pouvez probablement utiliser as.Date ou strptime directement avec l'agument de format, sans traiter les caractères plus loin. – mdsumner

Répondre

24

Vous pouvez être trop compliqué, avez-vous besoin du package stringr?

df <- data.frame(Date = c("10/9/2009 0:00:00", "10/15/2009 0:00:00")) 
as.Date(df$Date, "%m/%d/%Y %H:%M:%S") 

[1] "2009-10-09" "2009-10-15"

Plus généralement et si vous avez besoin du composant de temps ainsi, l'utilisation strptime:

strptime(df$Date, "%m/%d/%Y %H:%M:%S") 

Je devine à ce que vos données réelles pourraient regarder des résultats partiels que vous donnez.

+0

Je voudrais mettre en garde contre 'strptime' car il renvoie un objet' POSIXlt', ce qui tend à donner de nouveaux utilisateurs parce qu'ils ne réalisent pas qu'il s'agit d'une liste. Si vous avez besoin de temps, utilisez 'as.POSIXct' mais faites attention si vos" dates "sont vraiment des facteurs ... –

+1

true, mais puisque R 2.11.0" length () renvoie maintenant la longueur du timedate-vector abstrait correspondant plutôt que toujours 9 (la longueur de la structure de liste sous-jacente). (Souhait de PR # 14073 et PR # 10507.) "Je me demandais si cela valait la peine de compliquer les choses avec. Vous pouvez tout simplement as.POSIXct (strptime (x)) de toute façon. – mdsumner

+0

Je ne m'en suis pas rendu compte. Merci pour le pointeur. Bien que je me demande si cela peut encore prêter à confusion si vous avez une colonne 'POSIXlt' dans un' data.frame' ... –

30

La façon la plus simple est d'utiliser lubridate:

library(lubridate) 
prods.all$Date2 <- mdy(prods.all$Date2) 

Cette fonction retourne automatiquement les objets de la classe POSIXct et travaillera avec soit des facteurs ou des caractères.

+5

Je mentionnerai l'existence de choses comme ymd(), ymd_hms(), myd_hms(), etc. dans cette bibliothèque pour gérer ensemble les champs de date et d'heure. Awesome bibliothèque btw. Mes chapeaux à vous ... –

-1

library(lubridate) si votre format de date est comme ce '04/24/2017 05: 35: 00'then changer comme ci-dessous prods.all$Date2<-gsub("/","-",prods.all$Date2) puis changer le format de date parse_date_time(prods.all$Date2, orders="mdy hms")

Questions connexes