J'ai un ensemble de données avec une colonne de caractères pour les mois ( MONTH
) et une colonne numérique indiquant les années ( YEAR
). Pour pouvoir les utiliser comme données de panel, je dois unir ces YEAR
et MONTH
en une variable avec un format de date.
J'ai essayé de changer la variable MONTH
au format numérique puis pour fusionner MONTH
avec la colonne YEAR
. R ne le reconnaîtrait pas comme une variable de date.
Il ressemble actuellement à ceci:
STATE TIME VALUE California 01-2018 800 California 02-2018 780 California 03-2018 600 ... ... ... Minesota 01-2018 800 Minesota 02-2018 780 Minesota 03-2018 600 ... ... ...
Je le veux comme ceci:
STATE MONTH YEAR VALUE California JAN 2018 800 California FEB 2018 780 California MAR 2018 600 ... ... ... ... Minesota JAN 2018 800 Minesota FEB 2018 780 Minesota MAR 2018 600 ... ... ... ...
5 Réponses :
Dans la base R, vous pouvez faire quelque chose comme:
transform(df,TIME = paste(sprintf('%02d',match(MONTH,toupper(month.abb))),YEAR,sep = '-'))[c(1,5,4)] STATE TIME VALUE 1 California 01-2018 800 2 California 02-2018 780 3 California 03-2018 600 4 ... NA-... ... 5 Minesota 01-2018 800 6 Minesota 02-2018 780 7 Minesota 03-2018 600
Je recommanderais de gérer cela en passant par des dates R authentiques, en utilisant as.Date
pour générer une date R, puis en utilisant le format
pour afficher la chaîne que vous vouloir. Quelque chose comme ceci:
df$TIME <- format(as.Date(paste0(df$MONTH, df$YEAR, "01"), format="%b%Y%d"), "%m-%Y")
J'attribue arbitrairement la première à chaque date de votre ensemble de données, mais cela n'a pas d'importance, car l'appel au format
inclut uniquement le mois et année.
En combinant la réponse de Tim avec un package de date facile à utiliser lubridate
, nous obtenons:
# This can handle months of JAN, FEB, ETC. Or it can handle months of 01,02,etc. df$TIME <- lubridate::ymd(paste0(df$YEAR,df$MONTH,"01")) # or if you need it in MM-YYYY format: df$TIME <- format(lubridate::ymd(paste0(df$YEAR,df$MONTH,"01")), "%m-%Y")
Vous pouvez simplifier ce qui suit, mais cela permet de voir plus facilement ce qui se passe:
library(lubridate) library(tidyverse) df2 <- df %>% mutate(TIME = parse_date_time(paste0(MONTH, YEAR), orders = "%b%Y"), TIME = as.character(substr(TIME, 6, 7)), TIME = paste0(TIME, "-", YEAR))
Ceci utilise lubridate
- le moyen le plus simple d'analyser les dates dans R IMO, dplyr
de tidyverse
et substr
de base R.
Si vous souhaitez conserver la colonne de date, pipe dans un autre muter
et appeler la nouvelle colonne quelque chose de différent.
Si vous souhaitez utiliser une solution Tidyverse complète, envisagez cette combinaison de tidyr
et de lubridate
parse_date_time
:
library(tidyverse) df <- tibble::tribble( ~STATE, ~MONTH, ~YEAR, ~VALUE, "California", "JAN", 2018, 800, "California", "FEB", 2018, 780, "California", "MAR", 2018, 600, "Minesota", "JAN", 2018, 800, "Minesota", "FEB", 2018, 780, "Minesota", "MAR", 2018, 600) df %>% tidyr::unite(TIME, c(MONTH, YEAR), sep = "-") %>% dplyr::mutate(TIME = lubridate::parse_date_time(TIME, "my")) #> # A tibble: 6 x 3 #> STATE TIME VALUE #> <chr> <dttm> <dbl> #> 1 California 2018-01-01 00:00:00 800 #> 2 California 2018-02-01 00:00:00 780 #> 3 California 2018-03-01 00:00:00 600 #> 4 Minesota 2018-01-01 00:00:00 800 #> 5 Minesota 2018-02-01 00:00:00 780 #> 6 Minesota 2018-03-01 00:00:00 600
Consultez également la question connexe suivante: Conversion de l'année et du mois (au format" aaaa-mm ") en une date?
Une date nécessite le jour, le mois et l'année. Vous ajoutez donc le 1er de chaque mois comme un jour arbitraire avant le formatage de la date, ou utilisez
zoo :: as.yearmon
pour convertir en objets "année-mois". Voir la réponse de @ tim-biegeleisen pour la première approche.