web-dev-qa-db-fra.com

Spécifiez le format de date personnalisé pour l'argument colClasses dans read.table / read.csv

Question:

Existe-t-il un moyen de spécifier le format de date lorsque l’argument colClasses est utilisé dans read.table/read.csv?

(Je me rends compte que je peux convertir après l'importation, mais avec de nombreuses colonnes de date comme celle-ci, il serait plus facile de le faire à l'étape d'importation)


Exemple:

J'ai un .csv avec les colonnes de date au format %d/%m/%Y.

dataImport <- read.csv("data.csv", colClasses = c("factor","factor","Date"))

Cela entraîne une erreur de conversion. Par exemple, 15/07/2008 devient 0015-07-20.


Code reproductible:

data <- 
structure(list(func_loc = structure(c(1L, 2L, 3L, 3L, 3L, 3L, 
3L, 4L, 4L, 5L), .Label = c("3076WAG0003", "3076WAG0004", "3076WAG0007", 
"3076WAG0009", "3076WAG0010"), class = "factor"), order_type = structure(c(3L, 
3L, 1L, 1L, 1L, 1L, 2L, 2L, 3L, 1L), .Label = c("PM01", "PM02", 
"PM03"), class = "factor"), actual_finish = structure(c(4L, 6L, 
1L, 2L, 3L, 7L, 1L, 8L, 1L, 5L), .Label = c("", "11/03/2008", 
"14/08/2008", "15/07/2008", "17/03/2008", "19/01/2009", "22/09/2008", 
"6/09/2007"), class = "factor")), .Names = c("func_loc", "order_type", 
"actual_finish"), row.names = c(NA, 10L), class = "data.frame")


write.csv(data,"data.csv", row.names = F)                                                        

dataImport <- read.csv("data.csv")
str(dataImport)
dataImport

dataImport <- read.csv("data.csv", colClasses = c("factor","factor","Date"))
str(dataImport)
dataImport

Et voici à quoi ressemble la sortie:

code output

98
Tommy O'Dell

Vous pouvez écrire votre propre fonction qui accepte une chaîne et la convertit en Date en utilisant le format souhaité, puis utilisez le setAs pour la définir comme méthode as. Ensuite, vous pouvez utiliser votre fonction dans le cadre des colClasses.

Essayer:

setAs("character","myDate", function(from) as.Date(from, format="%d/%m/%Y") )

tmp <- c("1, 15/08/2008", "2, 23/05/2010")
con <- textConnection(tmp)

tmp2 <- read.csv(con, colClasses=c('numeric','myDate'), header=FALSE)
str(tmp2)

Puis modifiez si nécessaire pour travailler pour vos données.

Modifier ---

Vous voudrez peut-être exécuter setClass('myDate') en premier pour éviter l'avertissement (vous pouvez ignorer cet avertissement, mais cela peut devenir agaçant si vous le faites souvent et qu'il s'agit d'un simple appel qui s'en débarrasse).

153
Greg Snow

Si vous souhaitez modifier un seul format de date, vous pouvez utiliser le package Defaults pour modifier le format par défaut dans as.Date.character

library(Defaults)
setDefaults('as.Date.character', format = '%d/%M/%Y')
dataImport <- read.csv("data.csv", colClasses = c("factor","factor","Date"))
str(dataImport)
## 'data.frame':    10 obs. of  3 variables:
##  $ func_loc     : Factor w/ 5 levels "3076WAG0003",..: 1 2 3 3 3 3 3 4 4 5
##  $ order_type   : Factor w/ 3 levels "PM01","PM02",..: 3 3 1 1 1 1 2 2 3 1
##  $ actual_finish: Date, format: "2008-10-15" "2009-10-19" NA "2008-10-11" ...

Je pense que la réponse de @Greg Snow est bien meilleure, car elle ne modifie pas le comportement par défaut d'une fonction souvent utilisée.

25
mnel

Si vous avez besoin de temps aussi:

setClass('yyyymmdd-hhmmss')
setAs("character","yyyymmdd-hhmmss", function(from) as.POSIXct(from, format="%Y%m%d-%H%M%S"))
d <- read.table(colClasses="yyyymmdd-hhmmss", text="20150711-130153")
str(d)
## 'data.frame':    1 obs. of  1 variable:
## $ V1: POSIXct, format: "2015-07-11 13:01:53"
7
Mark Rajcok

Il y a longtemps, dans l'intervalle, le problème a été résolu par Hadley Wickham. Donc, de nos jours, la solution est réduite à une seule ligne:

library(readr)
data <- read_csv("data.csv", 
                  col_types = cols(actual_finish = col_datetime(format = "%d/%m/%Y")))

Peut-être que nous voulons même nous débarrasser de choses inutiles:

data <- as.data.frame(data)
1
Andri Signorell