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.yearmonpour convertir en objets "année-mois". Voir la réponse de @ tim-biegeleisen pour la première approche.