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.
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.
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.getSunlightTimes do pacote suncalc para calcular a duração do dia. Dessa maneira, eu adicionaria mais três argumentos na função: latitude, longitude e timezone. Esses são os mesmos argumentos usados pela função getSunlightTimes. (Tenho dúvida se essa é uma boa prática)sunrise == NULL & sunset == NULL) então:lat == NULL $ long == NULL) então:sunrise e sunset da função getSunlightTimesni = número intervalos possíveis dentro dos dados (total de dias dos dados/interval)niactivity.intervalsunrise e sunset usando getSunlightTimesnr = lenght(activity.interval) j de 1:nrj] está no intervalo entre sunrise e sunset?day.act = day.act + atividade do registro[j]night.act = night.act + atividade do registro[j]i] = (day.act - night.act)/(day.act + night.act)
<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>
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.
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.rtweettweetsggplot2lenght(keywords) > 1 então:tweets.summary que 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 tweeti de 1:lenght(keywords)tweets.keywords = grep(keyword[i], tweets)ggplot2tweets.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 tweettweets.summary que recebe os valores de média de tweets por dia, média de RTs por tweet e média de curtidas por tweet.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>
##################################
# 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
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