#========================================================================================== # Curso de capacitação em ambiente R - Conselho Nacional de Justiça (04/10/2012) # Walmes Zeviani & Paulo Justiniano - LEG/UFPR # # Datas e expressões regulares #========================================================================================== #------------------------------------------------------------------------------------------ # uma string que representa uma data precisa ser convertido para data # usando as.Date(), as.POSIX(), ISOdate(), strptime(), chron() nasc <- c(tukey="16/06/1915", cramer="25/09/1893", fisher="17/02/1890", kendall="06/09/1907", gosset="13/06/1876", pearson="27/03/1857", galton="16/02/1822", gauss="30/04/1777", laplace="23/03/1749", newton="04/01/1643", lagrange="25/01/1736", anscombe="18/03/1919") str(nasc) typeof(nasc) y <- as.Date(nasc, # vetor de string format="%d/%m/%Y") # composição da string y # formato aaaa-mm-dd class(y) typeof(y) names(y) <- names(nasc) sort(y) #------------------------------------------------------------------------------------------ # após conversão é possível fazer cálculos com datas d <- range(y) diff(d) methods(diff) help(diff.Date, help_type="html") difftime(max(y), min(y), units="weeks") # diferença em semanas difftime(max(y), min(y), units="month") # opções disponíveis #------------------------------------------------------------------------------------------ # extratores months(y) weekdays(y) quarters(y) julian(y) help(weekdays, help_type="html") # as.Date() só serve para datas com menor unidade de tempo sendo o dia # ou seja, não serve para datas com H:M:S #------------------------------------------------------------------------------------------ # passando de datas para string com formatos de leitura format(y, format="%A, %d de %B de %Y") # veja que não tem o "-feira" (colocar com REGEX) format(y, format="%a, %d %b %Y") # veja que não tem o "-feira" strftime(y, format="%a, %d %b %Y") strftime(Sys.time(), format="Hoje é uma %A, dia %d do mês de %B do ano de %Y") strftime(y, format="%j") # dia juliano #------------------------------------------------------------------------------------------ # sequencia de datas seq(as.Date("1700-01-01"), as.Date("1970-01-01"), by="year") seq(as.Date("1700-01-01"), as.Date("1970-01-01"), by="10 years") seq(as.Date("1700-01-01"), as.Date("1970-01-01"), by="100 years") seq(as.Date("1700-01-01"), as.Date("1970-01-01"), by="6 months") #------------------------------------------------------------------------------------------ # classificando datas em intervalos (decadas) min(y) decada <- seq(as.Date("1640-01-01"), as.Date("1970-01-01"), by="10 years") decada length(decada) wi <- findInterval(y, decada) wi data.frame(data=y, wi=wi, i=decada[wi], f=decada[wi+1]) #------------------------------------------------------------------------------------------ # classificando as datas em intervalos 2 (signos) # tabela no http://www.alienado.net/datas-dos-signos/ lines <- "Entre 20/03 e 20/04 são do signo de Áries. Entre 21/04 e 20/05 é de Touro. Entre 21/05 e 20/06 é Gêmeos. Entre 21/06 e 21/07 é Câncer. Entre 22/07 e 22/08 é Leão. Entre 23/08 e 22/09 é Virgem. Entre 23/09 e 22/10 é Libra. Entre 23/10 e 21/11 é Escorpião. Entre 22/11 e 21/12 é Sagitário. Entre 22/12 e 21/01 é Capricórnio. Entre 21/01 e 18/02 é Aquário. Entre 19/02 e 19/03 é Peixes." sig <- read.table(textConnection(lines), sep="\t", stringsAsFactors=FALSE) sig <- sig[,1] # usando expressão regular para pegar os intervalos i <- gsub("Entre.(\\d{2}/\\d{2}).e.*", "\\1", sig) # tira inicio i f <- gsub("Entre.*(\\d{2}/\\d{2}).*", "\\1", sig) # tira final f s <- gsub(".*\\s(.*)\\.$", "\\1", sig) # tira signo s # só precisamos do início para fazer a busca, vamos adicionar um ano i <- paste(i, "/2012", sep="") i <- as.Date(i, "%d/%m/%Y") s <- s[order(i)] i <- sort(i) names(i) <- s i # trocar o ano dos nascimentos para 2012 (que é ano bisexto, importante) w <- as.Date(paste("2012-", strftime(y, "%m-%d"), sep="")) names(w) <- names(nasc) ws <- findInterval(w, i) ws[ws==0] <- 12 data.frame(nascimento=y, signo=names(i)[ws]) table(names(i)[ws]) # tem mais aquariano!! #------------------------------------------------------------------------------------------ # o mesmo vale para estações do ano, estação chuvosa/seca, bimestres, etc... #------------------------------------------------------------------------------------------ # quando a data é numérica dac <- read.table("http://www.leg.ufpr.br/~walmes/ensino/ce223-2011-01/dac.txt") str(dac) dac <- dac$V1 dac[1] dac <- as.POSIXlt(dac, origin="1970-01-01") # esse valor e origem pode mudar dac <- sort(dac) str(dac) # pegando as horas de acesso apenas hac <- as.POSIXct(format(dac, "%H:%M:%S"), format="%H:%M:%S") # hora do acesso em função da data do acesso à página # apenas para ilustrar como fazer um gráfico de série no tempo plot(dac, hac, type="p", ylab="Hora do acesso", xlab="Data do acesso", xaxt="n") axis.POSIXct(1, at=seq(as.POSIXct("2010-10-01"), as.POSIXct("2011-06-15"), by="month"), format="%B", col=2) axis.POSIXct(3, at=seq(min(dac), max(dac), by="week"), format="%d/%m") axis.POSIXct(1, at=seq(as.POSIXct("2010-10-01"), as.POSIXct("2011-06-15"), by="3 days"), format="%d", col=2, labels=FALSE, tcl=-0.2) axis.POSIXct(2, at=seq(as.POSIXct("03:00:00", format="%H:%M:%S"), as.POSIXct("21:00:00", format="%H:%M:%S"), by="hour"), format="%H", labels=FALSE, tcl=-0.2) #------------------------------------------------------------------------------------------ # número de acessos por dia dia <- as.Date(strftime(dac)) nad <- table(dia) nad nad <- data.frame(dia=as.Date(names(nad)), ace=nad) str(nad) plot(ace.Freq~dia, nad, type="o") # identificar dias por cliques com identify with(nad, identify(dia, ace.Freq, labels=dia)) #------------------------------------------------------------------------------------------ # intervalo de tempo médio entre acessos por dia mean(diff(hac[1:3])) myfun <- function(x) mean(diff(x)) nad$mac <- tapply(hac, dia, myfun)/60 plot(mac~dia, nad, type="o", ylab="Minutos") #------------------------------------------------------------------------------------------ # número de acessos por semana do ano range(dac) strftime(dac[1], "%Y-%W") sem <- strftime(dac, "%Y-%W") ncas <- table(sem) plot(ncas) # o mesmo vale para meses do ano e dias da semana plot(table(strftime(dac, "%a"))) #------------------------------------------------------------------------------------------ # fazendo extrações das componentes (numeric), com strftime sai character x <- dac[sample(1:length(dac), 5)] x x$sec x$min x$hour x$mday x$mon x$year x$wday x$yday x$isdst #------------------------------------------------------------------------------------------ # diferença de POSIXct e POSIXlt as.POSIXct(Sys.time(), tz="GTM") as.POSIXlt(Sys.time(), tz="GTM") as.POSIXct(Sys.time(), tz="") as.POSIXlt(Sys.time(), tz="") #------------------------------------------------------------------------------------------ # usando a função ISOdate (você tem a data repartida nas unidades de medida) z1 <- ISOdate(2012, 12, 12, 12) # aaaa, mm, dd, hh; fim do mundo z2 <- Sys.time() # data do sistema operacional z1-z2 difftime(z1, z2, units="weeks") difftime(z1, z2, units="mins") difftime(z1, z2, units="hours") #------------------------------------------------------------------------------------------ # outra opção de uso é a library chron require(chron) help(chron, help_type="html") dtimes <- c("2002-06-09 12:45:40","2003-01-29 09:30:40", "2002-09-04 16:45:40","2002-11-13 20:00:40", "2002-07-07 17:30:40") dtparts <- t(as.data.frame(strsplit(dtimes," "))) row.names(dtparts) <- NULL thetimes <- chron(dates=dtparts[,1], times=dtparts[,2], format=c("y-m-d","h:m:s")) thetimes class(thetimes) # operações de soma, amplitude, etc também estão definidas para essa classe # algumas interessantes nasc[leap.year(as.chron(y))] # leap.year() retorna TRUE/FALSE para ano bisexto w <- format(w, "%m/%d/%y") i <- format(i, "%m/%d/%y") cut(dates(w), breaks=dates(i)) # na é o zero do Capricórnio #------------------------------------------------------------------------------------------ # vizualização dos dados de temperatura de galpões