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?
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"
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
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
"
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!
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.
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"