J'essaye d'importer une feuille de calcul Excel dans R (via read.xlsx2 ()
). Les données Excel ont une colonne de date. Cette colonne de date contient des types mixtes de formats de date, par exemple certaines lignes sont 42669
, et certaines sont au format date, par exemple 26/10/2016
.
read.xlsx2 ()
le lit comme un facteur, je l'ai donc converti en as.Date en utilisant le code ci-dessous. Cela fonctionne pour toutes les dates sous forme numérique (ex: 42669
) mais R me prévient qu'il a ajouté des NA
s (pour celles au format 26/10 / 2016
). Ma question est de savoir comment importer les données Excel avec des dates appropriées pour toutes les variables, c'est-à-dire dire à R qu'il y a des données mixtes?
library(xlsx) #Import excel file df <- read.xlsx2(mydata, 1, header=true) #Output = recd_date : Factor w/ 590 levels "", "26/10/2016", "42669" ... levels(df$recd_date) #Output = [1] "" "26/10/2016" "42669" ... #This works for numeric dates: df$recd_date <- as.Date( as.numeric (as.character(df$recd_date) ),origin="1899-12-30") #Output = recd_date : Date, format "2016-10-26" ... #but it doesn't work for dd/mm/yyyy dates, R just replaces these with NA
3 Réponses :
Nous pourrions appliquer une fonction pour nettoyer la date si nécessaire, en gros comme ceci:
> df2 X. date.chr date.num date.mix 1 1 2019-02-01 2019-02-01 2019-02-01 2 2 2019-02-02 2019-02-02 2019-02-02 3 3 2019-02-03 2019-02-03 2019-02-03
Exemple
date.cols <- c("date.chr", "date.num", "date.mix") # select date columns df2[date.cols] <- lapply(df2[date.cols], cleanDate)
Maintenant, nous appliquons la fonction en utilisant lapply()
.
# generate test df df1 <- data.frame(date.chr=as.character(as.Date(1:3, origin=Sys.Date())), date.num=as.numeric(as.Date(1:3, origin=Sys.Date())), date.mix=as.character(as.Date(1:3, origin=Sys.Date())), stringsAsFactors=FALSE) df1[2, 3] <- as.character(as.numeric(as.Date(df1[2, 1]))) > df1 date.chr date.num date.mix 1 2019-02-01 17928 2019-02-01 2 2019-02-02 17929 17929 3 2019-02-03 17930 2019-02-03 # write it to working directory library(xlsx) write.xlsx2(df1, "df1.xlsx") # read it # we use opt. `stringsAsFactors=FALSE` to prevent generation of factors df2 <- read.xlsx2("df1.xlsx", 1, stringsAsFactors=FALSE) > df2 X. date.chr date.num date.mix 1 1 2019-02-01 17928 2019-02-01 2 2 2019-02-02 17929 17929 3 3 2019-02-03 17930 2019-02-03
Result
cleanDate <- function(x) { if (all(nchar(df2$date.mix) < 10)) { cd <- as.Date(x) } else { cd <- do.call(c, lapply(x, function(i) if (nchar(i) < 10) as.Date(as.numeric(i), origin="1970-01-01") else as.Date(i))) } return(cd) }
Cela fonctionne-t-il avec différentes structures de date dans la même colonne?
@Chabo Merci, les questions doivent être lues attentivement ^^ Voir la réponse mise à jour.
Voici un moyen de le faire,
Une fois que nous avons lu les données, nous convertissons les colonnes de date (df $ recd_date) en caractère de classe, puis créons deux listes, une avec les dates jj / mm / AAAA, et l'autre avec les dates numériques. Une fois que cela est fait, nous convertissons indépendamment en classe de date, puis fusionnons les deux pour obtenir un produit final.
#Test Data, read in anyway you want data<-c("26/10/2016","27/10/2016","42669","52673","28/10/2016") Index<-c(1:5) df<-data.frame(Index, date=data) #Put entire date column into character format df$date<-as.character(df$date) #Create Date from Numeric Date, Create Date from Character Date Date_N<-as.Date(as.numeric(df$date),origin="1899-12-30") Date_C<-as.Date(as.character(df$date),format="%d/%m/%Y") #Create DF from list Date_N_df<-as.data.frame(Date_N) Date_C_df<-as.data.frame(Date_C) #Replace NA from Date_C_df with index from Date_N_df Date_C_df[is.na(Date_C_df)] <- Date_N_df[is.na(Date_C_df)] Final<-Date_C_df names(Final)<-"Date" > Final Date 1 2016-10-26 2 2016-10-27 3 2016-10-26 4 2044-03-17 5 2016-10-28
Je vous remercie. Cela a fonctionné aussi mais je pense que la réponse ci-dessus est plus ce que je recherchais.
Essayez convert_to_date
à partir du package de conciergerie, en spécifiant la fonction character-to-date du package lubridate qui correspond à votre format de date:
library(janitor) x <- c("26/10/2016", "42669") convert_to_date(x, character_fun = lubridate::dmy) #> [1] "2016-10-26" "2016-10-26"
Self -promotion disclaimer: je maintiens ce package. J'ajoute cette réponse car cette fonction a été créée pour résoudre ce problème exact d'un mélange de numéros de date Excel et de dates formatées dans la même variable.
Ne serait-il pas plus facile de changer toutes les dates au même format dans Excel?
J'ai essayé cela en premier, mais pour une raison quelconque, certains champs sont restés dans le mauvais format et j'ai de nombreuses colonnes de date à parcourir