Jefferson Tiago Silvério da Silva
Aluno de mestrado no Departamento de Fisiologia, IB-USP, no laboratório de Cronobiologia Animal, sob orientação da Prof. Dra. Gisele Oda. Desenvolvo projeto sobre fotoperiodismo e sazonalidade reprodutiva em roedores subterrâneos do gênero Ctenomys.
Meus Exercícios
Projeto Final
Proposta A: Indíce de diurnalidade
Contextualização
Em estudos de padrões de atividade e ritmos biológicos o índice de diurnalidade, proposto por Hoogenboom (1984), é usado para medir o quanto um animal está noturno ou diurno. Esse índice é particularmente útil em estudos que avaliam a alteração do padrão de atividade sazonal ou de animais que mudam de noturnos para diurnos em certas situações experimentais. O Índice de diurnalidade é uma proporção entre a quantidade de atividade exibida durante as horas de claro e a atividade durante a fase de escuro. O índice é simétrico ao redor de 0 e pode variar de -1 até 1, onde 1 representa um animal completamente diurno e -1 um animal completamente noturno. Esse índice é calculado pela equação abaixo, onde Cd é a quantidade de atividade diurna e Cn é a quantidade de atividade noturna.
$$D = (C_d - C_n)/(C_d + C_n)$$
O objetivo da função é calcular o índice de diurnalidade de um intervalo de dias qualquer ao longo de um conjunto de dados.
Entrada
diurnality (datetime, activity, interval = 1, sunrise = NULL, sunset = NULL, lat, long, timezone)
datetime= Vetor de datahora no formato POSIXctactivity= Vetor numéricointerval= Número inteiro de dias para calculo do índice.sunrise= Horário de nascer do sol em formato HH:MM.sunset= Horário de por do sol em formato HH:MM.
- Receber o horário do nascer e do por do sol pelo usuário funcionará bem em casos onde dados não se estendam por um tempo muito longo. Porém, caso o volume de dados seja grande e se estenda por um ano, por exemplo, é necessário calcular a duração do dia a medida que o índice é calculado.
- Nesse caso pensei em usar a função
getSunlightTimesdo pacotesuncalcpara calcular a duração do dia. Dessa maneira, eu adicionaria mais três argumentos na função:latitude,longitudeetimezone. Esses são os mesmos argumentos usados pela funçãogetSunlightTimes. (Tenho dúvida se essa é uma boa prática)
Pseudocódigo
- Verificar argumentos:
- Se (
sunrise== NULL &sunset== NULL) então:- Se (
lat== NULL $long== NULL) então:- Warning (“Fornecer dados para calculo do fotoperíodo”)
- Senão obtem valores de
sunriseesunsetda funçãogetSunlightTimes
ni= número intervalos possíveis dentro dos dados (total de dias dos dados/interval)- For de i de 1:
ni- Atribuir dados que estão dentro do intervalo a um novo vetor
activity.interval - Recalcula
sunriseesunsetusandogetSunlightTimes nr=lenght(activity.interval)- For
jde 1:nr- Horário do registro[
j] está no intervalo entre sunrise e sunset? - Se sim
day.act=day.act+ atividade do registro[j] - Se não
night.act=night.act+ atividade do registro[j]
- Fim do loop
- Calcular índice do intervalo diurnality[
i] = (day.act-night.act)/(day.act+night.act)
- Fim do Loop
Saída
- Um vetor com os índices calculados.
- Um gráfico de pontos mostrando a variação da diurnalidade ao longo do tempo, semelhante a:
Referências
<box 100% red| Comentários Lucas Freitas>
Acredito que essa primeira proposta seja a mais interessante! Quanto o objetivo tudo OK, vc está transformando uma tarefa necessária e cansativa em algo que uma vez organizado fica extremamente conveniente. Aqui vão minhas pontuações.
Ambas as estratégias de obtenção de dados de sunrise e sunset são válidas. Você pode sim utilizar o pacote suncalc para calcular esses valores dentra da sua função. Nao se esqueca de optimizar os warnings no começo para que o usuário saiba que um dos dois conjuntos: (sunrise e sunset) ou (lat, long, null , timezone) deve estar completo e os elementos do outro conjunto devem estar vazios.
Dica: crie duas variáveis dentro da função(bottom.limit upper.limit) e use testes lógicos para guardar os valores de sunset e sunrise conforme a utilização de ou o input dos dados ou sua aquisição com o get SunlightTimes.
Dica 2. Cuidado ao extrair os valores com a função getSunlightTimes. O formato dos horários na variável resposta pode não ser o desejado. Se necessário é possível a extração de elementos de strings com outras funções. (formas de conversão mais simples também devem existir)
O argumento Interval é desnecessário, uma vez que esse valor deve ser o mesmo de o tamanho do vetor de sunrise e/ou sunset (se eu entendi direito).
Nao entendi exatamente como os dados estão organizados:
Datetime seria uma matriz em que cada linha representa o o início de uma atividade que foi realizada pelo indivíduo observado no formato POSIXct? Ela contém a data e o Horário? Eles estão juntos em uma variável ou cada um em colunas diferentes? Pense nisso na hora de elaborar os cálculos. Activity seria um vetor contendo a duração de tempo de cada uma das atividades iniciadas na respectiva posição em datetime?
De qualquer forma imagino que em algum lugar estão os: Inícios das observações, tempo das observações e o valores referentes a proporcao dia e noite na combinação dos dados e isso seria o bastante para o cálculo de apenas um indivíduo.
O que acontece se a atividade começa durante o dia e termina de noite?
Talvez nomear os elementos do vetor resposta, uma vez calculado, seja interessante. Da forma como vc pensou acredito que fique fácil fazer a confecção do gráfico no final com base variação do índice.
</box>
<box 100% blue| Jefferson>
Oi, Lucas. Obrigada pelos comentários. Bom, acho que na minha proposta ficaram faltando explicar algumas coisas. Os dados desses tipos geralmente vem em formato de texto. O arquivo geralmente tem duas colunas, uma com a data e hora e a outra com a atividade correspondente aquele. Um exemplo de dados de acelerômetro registrando a atividade a cada 5 minutos, durante 23 dias, seria:
datetime activity 05/03/2019 08:05:30.000 0.075 05/03/2019 08:10:30.000 0.057 05/03/2019 09:05:30.000 0.170 05/03/2019 09:10:30.000 0.210 05/03/2019 09:15:30.000 0.241 . . . 28/03/2019 22:05:30.000 0.000 28/03/2019 22:10:30.000 0.001 28/03/2019 22:05:30.000 0.020 28/03/2019 22:10:30.000 0.009
Então, penso que para tornar a função mais flexível o melhor seria que ambos os argumento de entrada datetime e activity sejam vetores. O usuário leria esse conjunto de dados, provavelmente como dataframe, trataria como necessário e poderia passar os argumentos para a função tanto indexando o dataframe quanto usando vetores separados.
Acho que uma coisa que não ficou muito claro na minha proposta inicial é que nem sempre o indíce é calculado por dia. Por exemplo, dentro desse conjunto de dados poderia calcular o índice de diunalidade por dia e no final receberia um vetor com 23 linhas correspondentes ao indíce de cada um dos dias. Porém, dependendo da duração do registro ou do objetivo do trabalho, talvez eu queira calcular o indice de diurnalide a cada 5 dias, ou a cada 30 dias. Esse número de dias para o qual o índice vai ser calculado é o que eu nomeei deinterval nos argumentos.
A idéia, então, é receber o intervalo de dias para o qual o índice vai ser calculado. Dentro desse intervalo, separar o que é atividade diurna e o que é atividade noturna. Por fim, calcular o índice correspondete ao intervalo de dias fornecido pelo usuário.
</box>
Proposta B: Plotando Tweets
O twitter é, infelizmente, o meio de comunicação oficial de Bolsonaro. Acompanhar as postagens do presidente, no entanto, é um exercício de paciência. Assim, minha segunda proposta é fazer uma função que receba o nome de um usuário qualquer do twitter e retorne alguns gráficos que sumarizem o número de tweets, RTs e curtidas por dia. Além disso, permitir ao usuário fornecer uma ou mais palavras chaves para fazer uma busca específica dentro dos twitts. A idéia é reproduzir algo como feito nesse artigo do Nexo porém para uso continuo.
Entrada
plot.tweet(user, n = 1000, keywords = NULL)
user= nome do usuário no twitter.keywords= palavras chaves a serem buscadas nos tweets do usário.n= número de tweets a serem recuperados, dever ser menor do que 3200.
Pseudocódigo
- Verificar argumentos
- Conectar com API do twitter usando o pacote
rtweet - Fazer chamada para recuperar dados do usuário desejado
- Atribui o resultado da busca à variável
tweets - Plot de Quantidade de tweets, RTs e curtidas em formato de calendário usando
ggplot2
- Se
lenght(keywords)> 1 então:- Cria uma lista
tweets.summaryque recebe na posição [ [1] ] os valores de média de tweets por dia, média de RTs por tweet e médias de curtidas por tweet - For
ide 1:lenght(keywords)tweets.keywords=grep(keyword[i], tweets)- Plot de quantidade de tweets por palavra chave usando
ggplot2 tweets.summary[ [i+1] ]recebe os valores da média de tweets com a palavra chave por dia, média de RTs por tweet e médias de curtidas por tweet
- Fim do for
- Se não:
- Cria uma vetor
tweets.summaryque recebe os valores de média de tweets por dia, média de RTs por tweet e média de curtidas por tweet.
Saída
- Uma lista ou vetor com os valores médios de tweets por dia, RTs por tweet e curtidas por tweet
- Gráficos do tipo heatmap com a quantidade de tweets, RTs e curtidas por dia
Alguns Links
http://r-statistics.co/Top50-Ggplot2-Visualizations-MasterList-R-Code.html#Calendar%20Heat%20Map http://www.roymfrancis.com/calendar-plot-with-ggplot2/
<box 100% red| Comentários Lucas Freitas>
Quanto a segunda proposta não entendo nem de twitter nem da função retweet. Maaaaaaas, se você conseguir acesso a um arquivo contendo as informações necessárias:
1. todos os Tweets em strings
2. a data da publicação deles
3. o número de Retweets de cada um deles
Acredito que se fizer o proposto pelo pseudocódigo terá sucesso
Peço desculpas se entendi algo errado . Qualquer coisa estou a disposição.
Email: rodriguesdefreitaslucas@gmail.com Boa sorte.
</box>
Proposta 1: Função Diurnality
- diurnality.r
################################## # Calculo do indice de diunalidade # Jefferson Silva ################################### diurnality = function(datetime, activity, interval = 1, lat = NULL, lon = NULL, sunrise = NULL, sunset = NULL, graph = TRUE){ # checa se pacotes necessários estão instalados if (!require(suncalc)){ # Instala pacotes caso não estejam instalados install.packages("suncalc") }else { # carrega pacotes necessários # suncalc é usado para calcular a duração do dia em determinado dia do ano dado as coordenadas do local require(suncalc) } ##################### # Verifica argumentos ##################### #### Datetime deve ser do tipo POSIXct para evitar erros futuros if(!inherits(datetime, "POSIXct")){ # caso não seja a função é parada stop("Argumento 'datetime' deve ser da classe POSIXct") } # Intervalo para calculo do indice deve ser > 1 if(interval<=0){ stop("Argumento 'interval' deve ser >= 1") } if(!is.numeric(activity)){ stop("Argumento 'activity' deve ser numérico.") } if(length(activity) != length(datetime)){ stop("Argumentos 'datetime' e 'activity'devem ter o mesmo tamanho.") } #### Devem ser preenchido (sunrise e sunset) ou então (lat, lon) if(is.null(sunrise) | is.null(sunset)){ if(is.null(lat) | is.null(lon) ){ # Nenhum dos conjuntos de argumentos foi fornecido stop("É necessário fornecer manualmente o valor de nascer e pôr do sol ou as coordenadas do local.") } else{ # caso apenas lat lon sejam fornecidas cat(">>> A duração do dia será automaticamente calculada usando as coordenadas fornecidas.\n") # atrbui TRUE para uma variavel indicadora, o que significa que a duração do dia seá calculada usando o pacote suncalc coord = TRUE } } else{ if(is.null(lat) | is.null(lon)){ # checa se sunrise e sunset estão no formato correto de HH:MM if ( is.na(as.POSIXct(paste(Sys.Date(), sunset), format = "%Y-%m-%d %H:%M")) | is.na(as.POSIXct(paste(Sys.Date(), sunrise), format = "%Y-%m-%d %H:%M"))) { stop("'Sunrise' ou 'Sunset' não estão no formato HH:MM.") } else{ # caso apenas sunrise e sunset sejam fornecidos cat(">>> A duração do dia será feita com base no horário de nascer e pôr do sol fornecidos.") } # atrbui FALSE, indicando que será usado os valores de sunrise e sunset fornecidos pelo usuário coord = FALSE } else{ # Os dois conjuntos de argumentos foram fornecidos stop("Apenas um conjunto de argumentos deve ser fornecido entre horário de nascer e pôr do sol e as coordenadas.") } } #################### ## calcula indice ## #################### # Combina dados de entrada em um dataframe, o que facilita a manipulação. df = data.frame(datetime, activity) # omite NAs df = na.omit(df) # Usar coordenadas para calculo da duração do dia? if (coord == FALSE){ ## Esse bloco de código cria uma nova coluna no dataframe ## A nova coluna 'daylight' indica que o registro correspondente aquela linha foi realizado durante o dia # Para cada linha extrai somente o valor da data, descartando as horas dates = as.Date(df$datetime) # concatena a data correspondete daquela linha com o horário de nascer e pôr do sol sunrise = paste(dates, sunrise) sunset = paste(dates, sunset) # Verifica se o registro foi feito entre as horas de nascer e por do sol e adiciona a nova coluna 'daylight' ao dataframe df$daylight = ifelse(test = df$datetime >= sunrise & df$datetime <= sunset, yes = TRUE, no = FALSE) } else{ ## Para conseguir dados de nascer e por do sol, temos três opções em três pacotes diferentes: ## suncalc::getSunlightTimes, maptools::sunriset e StreamMetabolism::sunrise.set ## Em tempo de execuçao suncalc::getSunlightTimes foi mais rápido do que as outras funçoes # cria novo vetor com as datas de nasce e por do sol para cada linha do df sun = getSunlightTimes(as.Date(df$datetime), lat = lat, lon = lon, keep = c("sunrise", "sunset")) # Verifica se df está entre as horas de nascer e por do sol e adiciona a nova coluna 'daylight' ao dataframe. df$daylight = ifelse(test = df$datetime >= sun$sunrise & df$datetime <= sun$sunset, yes = TRUE, no = FALSE) } # Cria uma string de acordo com o intervalo de dias fornecido nos argumentos b = paste(as.character(interval),"days") # Cria um fator que corresponde ao intervalo de cada uma das linhas do df. cuts = cut(x = df$datetime, breaks = b) # Cria uma lista dividida por intervalos datetime.list = split(x = df, f = cuts) # Separa atividade que acontece durante dia ou noite e calcula o indice de diurnalidade (Hoogenboom, 1984) d.index = sapply(datetime.list, function(x){ # indexa valores de atividade que acontecem durante o dia actv.day = x$activity[x$daylight] # indexa valores de atividade que acontecem durante a noite actv.night = x$activity[!x$daylight] # somatória da atividade diurna actv.day = sum(actv.day) # somatória da atividade noturna actv.night = sum(actv.night) # calculo do indice de diurnalidade (Hoogenboom, 1984) d = (actv.day - actv.night)/(actv.day + actv.night) } ) ########## ## plot ## ########## if(graph){ # Prepara variaveis para criar retangulo e label do eixo X n = length(d.index) date.axis = strptime(names(d.index),"%Y-%m-%d") # Define como exibir as legendas if(interval >= 30){ # Para intervalos maiores do que 30 dias exibe o nome do mês e o ano. date.axis = format(date.axis, "%b\n%Y") } else{ # Para intervalos menores do que 30 dias exibe dia e nome do mês. date.axis = format(date.axis, "%d\n%b") } # prepara paramentros gráficos par(pch=16, tcl=-0.3, bty="l", cex.axis = 0.9, las = 1, cex.lab=1, mar=c(4,4,2,2)) # plota pontos plot(d.index, main = "", xlab = "", xaxt = "n", ylab = "Diurnality Index", ylim = c(-1,1) ) # adiciona eixo X axis(1, at=1:n, labels=date.axis, mgp = c(3, 1.5, 0)) # adiciona retangulo cinza na parte noturna do indice rect(xleft = c(-1,-1), ybottom = c(-2,-2), xright = c(n+2,n+2), ytop = c(0,0), col = rgb(0,0,0,0.009), lty=3, border = NA) # conecta pontos lines(x = 1:n, y = d.index, col = rgb(0,0,0,0.2), type = "b") # adiciona linha horizontal abline(h = 0, lty = 3, col = rgb(0,0,0,0.5)) } ############ ## return ## ############ return(d.index) } #FIM DIURNALITY
- help_diurnality.txt
diurnality package:unknown R Documentation CÁLCULO DO ÍNDICE DE DIURNALIDADE Description: Função para calcular o índice de diunalidade (Hoogenboom, 1984) usado em estudos de ritmos biológicos. A função pode calcular o índice de diurnalidade usando dados de nascer e pôr-do-sol fornecidos pelo usuário ou calcular esses horários automaticamente pelas coordenadas geográficas do local de coleta. Além disso, produz um gráfico para visualização dos resultados. Usage: diurnality(datetime, activity, interval = 1, lat = NULL, lon = NULL, sunrise = NULL, sunset = NULL, graph = TRUE) Arguments: datetime: Um vetor da classe POSIXct que corresponde a data e o horário das coletas de dados. activity: Um vetor numérico que corresponde a atividade exibida em cada ponto de coleta de dados. interval: Número >= 1 que corresponde ao intervalo no qual o indíce de diurnalidade devera ser calculado. Como padrão o índice é calculado diariamente. lat: Latitude em valor numérico para cálculo automático da duração do dia. lon: Longitude em valor numérico para cálculo automático da duração do dia. sunrise: Caracter em formato HH:MM. Horário de nascer do sol para cálculo da duração do dia. Caso 'sunrise' e 'sunset' sejam fornecidos a duração do dia se manterá a mesma ao longo do tempo. sunset: Caracter em formato HH:MM. Horário de pôr-do-sol para cálculo da duração do dia. Caso 'sunrise' e 'sunset' sejam fornecidos a duração do dia se manterá a mesma ao longo do tempo. graph: Logical. TRUE para exibição do gráfico. FALSE para não exibir o gráfico. Details: O índice de diurnalidade é calculado de acordo com a atividade exibida durante o dia ou durante a noite. Em casos onde a coleta de dados se extenda por um longo período de tempo, a duração do dia pode ser calculada automaticamente caso os argumentos 'lat, 'lon' sejam fornecidos. Caso a coleta de dados seja feita em ambiente de laboratório com luminosidade controlada, a duração do dia pode ser fornecida manualmente usando os argumentos 'sunrise' e 'sunset'. Somente um desses conjuntos de argumentos deve ser fornecido. Value: Um vetor numérico com os valores dos indíces calculados. Gráfico de pontos com os valores dos indices de diunalidades calculados em função do tempo. Warning: Se algum dos argumentos não for inserido corretamente a função não será executada, retornando uma mensagem de erro para identificação do problema. Author(s): Jefferson Silvério jt.silverio@usp.br References: Hoogenboom, I., Daan, S., Dallinga, J.H. et al. Oecologia (1984) 61: 18. https://doi.org/10.1007/BF00379084 See Also: suncalc suncalc::getSunlightTimes Examples: datetime = seq(ISOdate(2018,7,1), ISOdate(2019,7,1), "5 min") # Gera dados de Julho/2018 até Julho/2019 com intevalos de 5 minutos activity = rpois(length(datetime), 5) # Gera dados de atividade diurnality(datetime = datetime, activity = activity, lat = -23.5489, lon = -46.6388) # Coordenadas de SP diurnality(datetime = datetime, activity = activity, interval = 5, lat = -23.5489, lon = -46.6388) # Coordenadas de SP, calculado a cada 5 dias diurnality(datetime = datetime, activity = activity, interval = 30, lat = -23.5489, lon = -46.6388) # Coordenadas de SP, calculado a cada 30 dias diurnality(datetime = datetime, activity = activity, interval = 2, lat = -28.8, lon = -66.934) # Coordenadas de La Rioja, Argentina. Calculado a cada 2 dias diurnality(datetime = datetime, activity = activity, interval = 5, sunrise = "07:00", sunset = "18:00") # Horário dos crespuculos se mantém constante, calculado a cada 5 dias