web-dev-qa-db-fra.com

Format date en année/trimestre

J'ai le dataframe suivant:

Data <- data.frame(
  date = c("2001-01-01", "2001-02-01", "2001-03-01", "2001-04-01", "2001-05-01", "2001-06-01"),
  qtr = c("NA", "NA","NA","NA","NA","NA")
)

Je veux remplir Data $ qtr avec Year/Quater - f.e. 01/01 (j'ai besoin de ce format!).

J'ai écrit une fonction:

fun <- function(x) { 
  if(x == "2001-01-01" | x == "2001-02-01" | x == "2001-03-01") y <- "01/01"
  if(x == "2001-04-01" | x == "2001-05-01" | x == "2001-06-01") y <- "01/02"
  return(y)
}
n$qtr <- sapply(n$date, fun)

Mais ça ne marche pas. Je reçois toujours le message d'erreur:

Error in FUN(X[[1L]], ...) : Object 'y' not found

Pourquoi?

11
feder80

Vous devez expliquer Vectorize votre fonction: 

fun_v <- Vectorize(fun, "x")
fun_v(Data$date)
#[1] "01/01" "01/01" "01/01" "01/02" "01/02" "01/02"

Cependant, lorsqu'il s'agit de tâches plus ou moins standard (telles que les manipulations datetime), il existe toujours une solution déjà disponible:

library(Zoo)
yq <- as.yearqtr(Data$date, format = "%Y-%m-%d")
yq
#[1] "2001 Q1" "2001 Q1" "2001 Q1" "2001 Q2" "2001 Q2" "2001 Q2"

Pour convertir à votre format spécifique, utilisez 

format(yq, format = "%y/0%q")
#[1] "01/01" "01/01" "01/01" "01/02" "01/02" "01/02"
26
tonytonov

Utilisation des fonctions de base:

Data$date <- as.Date(Data$date)
Data$qtr <- paste(format(Data$date, "%y"), 
                  sprintf("%02i", (as.POSIXlt(Data$date)$mon) %/% 3L + 1L), 
                  sep="/")

#         date   qtr
# 1 2001-01-01 01/01
# 2 2001-02-01 01/01
# 3 2001-03-01 01/01
# 4 2001-04-01 01/02
# 5 2001-05-01 01/02
# 6 2001-06-01 01/02
10
Roland

J'adore le package lubridate pour travailler avec des dates. Super glissant. La fonction quarter trouve le trimestre (bien sûr) et ensuite le lie à l'année.

library(lubridate)
Data <- Data %>%
  mutate(qtr = paste0(substring(year(date),2,4),"/0",quarter(date))) 

Si vous n'êtes pas familier avec le %>%, la première ligne indique essentiellement "utilisez un cadre de données appelé data" et la deuxième ligne indique "muter (ou ajouter) une colonne appelée qtr

3
Jeff Parker

J'ai créé un format similaire avec quarter () et sub () dans R:

  Data$qtr <- paste(format(Data$date, "%y/"), 0, 
              sub( "Q", "", quarters(Data$date) ), sep = "")

J'espère que cela t'aides!

2
Beginning_Math

Un autre moyen (plus long) de le faire en utilisant si les déclarations est la suivante:

month <- as.numeric(format(date, format = "%m"))[1]

if (month < 4) {
    quarter <- paste( format(date, format = "%Y")[1], "Q1", sep="-")
} else if (month > 3 & month < 7) {
    quarter <- paste( format(date, format = "%Y")[1], "Q2", sep="-")            
} else if (month > 6 & month < 10) {
    quarter <- paste( format(date, format = "%Y")[1], "Q3", sep="-")
} else if (month > 9) {
    quarter <- paste( format(date, format = "%Y")[1], "Q4", sep="-")
}

Renvoie une chaîne au format: 

> quarter
[1] "2001-Q1"

Ensuite, vous pouvez étendre cela en utilisant une boucle.

0
Dominic
yq=function(x,prefix="%Y",combine="Q") paste0(ifelse(is.null(prefix),"",format(x,"%Y")),floor(as.numeric(format(x,"%m"))/3-1e-3)+1,sep=combine)

cela donne la flexibilité de retourner n'importe quel format qui a le quart dedans

pas besoin de chron ou zoo

comme pour votre exemple 

yq(as.Date("2013-04-30"),prefix="%y",combine="/0")
> [1] "13/02"
0
yonicd