Micronet

Tracking the consequences of environmental change requires information on both the physical and biological characteristics of ecological systems. Large-scale environmental data are now widely available from many data repositories. However, these data sets often need to be down-scaled in order to be paired with local ecological measurements. Hence, micro-environmental sensors are sometimes useful to integrate scales of ecological information relevant to global change. This is an open-source, collaborative network of micro-environmental sensors deployed globally.

micronet

ecoblender

load functions

# combine multiple csv files into one dataframe ###
concat <- function(fileList){
dflist <- data.frame() ## create empty dataframe
for(i in 1:length(fileList)){
loadfile<-read.csv(fileList[i]) ## read each csv file for loop
loggerID <- basename(fileList[i]) ## root file name
loggerID = substr(loggerID, 1, nchar(loggerID)-4) ## drop csv
loadfile[,"loggerID"] <- rep(loggerID,nrow(loadfile)) ## add logger ID to column
dflist<-rbind(dflist,loadfile) ## concatenate previous csv to main dataframe
}
return(dflist)
}

## calculates summary statistics of logger data
## includes minimum, maximum, mean, standard deviation, number of observations, start date of logger, end date of logger, duration of logger recording, and response variable.

summary.stat <- function(fileList, resp){
dflist <- data.frame() ## create empty dataframe
## combine into one dataframe
for(i in 1:length(fileList)){
loadfile<-read.csv(fileList[i]) ## read each csv file for loop
loggerID <- basename(fileList[i]) ## root file name
loggerID = substr(loggerID, 1, nchar(loggerID)-4) ## drop csv
## add detailed time statistics
t.str <- strptime(loadfile[,"Date"], "%m/%d/%Y %H:%M")
loadfile[,"days"] <- as.Date(format(t.str, "%m/%d/%Y"), "%m/%d/%Y") ## separate date
loadfile[,"hours"] <- as.numeric(format(t.str, "%H")) ##specify hour logged
loadfile[,"minutes"] <- as.numeric(format(t.str, "%M")) ## specify minutes logged
obs <- nrow(loadfile) ## number of observations
start.date <- min(loadfile[,"days"]) ## day logger first started
end.date <- max(loadfile[,"days"]) ## day logger ended
duration <- as.numeric(difftime(end.date,start.date)) ## duration of logger activity
resp.stat <- function(fileList, resp){
resp.min <- min(fileList[,resp]) ## minimum of response
resp.max <- max(fileList[,resp]) ## maximum of response
resp.mean <- mean(fileList[,resp]) ## mean of response
resp.sd <- mean(fileList[,resp]) ## standard deviation of response
sum.stat <- data.frame(resp.min,resp.max,resp.mean,resp.sd,obs,start.date,end.date,duration,resp)
colnames(sum.stat) <- c("min","max","mean","sd","observations","start.date","end.date","duration","Response")
return(sum.stat)
}
sum.stat <- resp.stat(loadfile, resp)
sum.stat[,"loggerID"] <- loggerID
dflist <- rbind(dflist, sum.stat)
}
return(dflist)
}

## error bar functions
source("errorbar.functions.r")

summary stats on sample data

## load hobo data files
fileList<-list.files("sample.data\\",pattern=".csv$",full=T)

## view file list
fileList
## [1] "sample.data\\Allan_Laroque.csv" "sample.data\\Carrot.csv"       
## [3] "sample.data\\Charles_Sule.csv"  "sample.data\\Doro_ground.csv"  
## [5] "sample.data\\Earth.csv"
## extract summary statistics of light data
Temp.summary <- summary.stat(fileList, "Temperature")
Luxavg.summary <- summary.stat(fileList, "Avg.light")
Luxmax.summary <- summary.stat(fileList, "Max.light")
Total.summary <- rbind(Temp.summary,Luxavg.summary,Luxmax.summary)
Total.summary
##       min        max        mean          sd observations start.date
## 1  -5.995     36.187    17.72612    17.72612         3342 2013-04-19
## 2  -6.120     45.452    19.64054    19.64054         3340 2013-05-01
## 3  -4.758     43.844    19.93838    19.93838         3340 2013-05-01
## 4   1.112     46.593    21.70595    21.70595         3340 2013-05-01
## 5  -7.267     44.580    19.15374    19.15374         3340 2013-05-01
## 6   0.000 220445.900  3854.04216  3854.04216         3342 2013-04-19
## 7   0.000 209423.600 19189.79108 19189.79108         3340 2013-05-01
## 8   0.000 253512.800 24466.20401 24466.20401         3340 2013-05-01
## 9   0.000 253512.800 15502.10931 15502.10931         3340 2013-05-01
## 10  0.000 253512.800 19940.18389 19940.18389         3340 2013-05-01
## 11  0.000 220445.900  3854.04216  3854.04216         3342 2013-04-19
## 12  0.000 209423.600 19189.79108 19189.79108         3340 2013-05-01
## 13  0.000 253512.800 24466.20401 24466.20401         3340 2013-05-01
## 14  0.000 253512.800 15502.10931 15502.10931         3340 2013-05-01
## 15  0.000 253512.800 19940.18389 19940.18389         3340 2013-05-01
##      end.date duration    Response      loggerID
## 1  2014-01-22      278 Temperature Allan_Laroque
## 2  2014-02-03      278 Temperature        Carrot
## 3  2014-02-03      278 Temperature  Charles_Sule
## 4  2014-02-03      278 Temperature   Doro_ground
## 5  2014-02-03      278 Temperature         Earth
## 6  2014-01-22      278   Avg.light Allan_Laroque
## 7  2014-02-03      278   Avg.light        Carrot
## 8  2014-02-03      278   Avg.light  Charles_Sule
## 9  2014-02-03      278   Avg.light   Doro_ground
## 10 2014-02-03      278   Avg.light         Earth
## 11 2014-01-22      278   Max.light Allan_Laroque
## 12 2014-02-03      278   Max.light        Carrot
## 13 2014-02-03      278   Max.light  Charles_Sule
## 14 2014-02-03      278   Max.light   Doro_ground
## 15 2014-02-03      278   Max.light         Earth

combining multiple dataframes

data.hobo <- concat(fileList)
str(data.hobo)
## 'data.frame':    16702 obs. of  6 variables:
##  $ ID         : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Date       : Factor w/ 3481 levels "1/1/2014 0:00",..: 1369 1370 1371 1372 1373 1374 1375 1381 1384 1385 ...
##  $ Temperature: num  25.7 25.1 19.9 17.9 15.3 ...
##  $ Avg.light  : num  43.1 0 0 0 0 0 0 0 0 0 ...
##  $ Max.light  : num  43.1 0 0 0 0 0 0 0 0 0 ...
##  $ loggerID   : chr  "Allan_Laroque" "Allan_Laroque" "Allan_Laroque" "Allan_Laroque" ...
head(data.hobo,10)
##    ID            Date Temperature Avg.light Max.light      loggerID
## 1   1 4/19/2013 12:00      25.708      43.1      43.1 Allan_Laroque
## 2   2 4/19/2013 14:00      25.125       0.0       0.0 Allan_Laroque
## 3   3 4/19/2013 16:00      19.853       0.0       0.0 Allan_Laroque
## 4   4 4/19/2013 18:00      17.950       0.0       0.0 Allan_Laroque
## 5   5 4/19/2013 20:00      15.282       0.0       0.0 Allan_Laroque
## 6   6 4/19/2013 22:00      12.690       0.0       0.0 Allan_Laroque
## 7   7  4/20/2013 0:00      10.748       0.0       0.0 Allan_Laroque
## 8   8  4/20/2013 2:00       9.275       0.0       0.0 Allan_Laroque
## 9   9  4/20/2013 4:00       7.882       0.0       0.0 Allan_Laroque
## 10 10  4/20/2013 6:00       6.268       0.0       0.0 Allan_Laroque
tail(data.hobo,10)
##         ID           Date Temperature Avg.light Max.light loggerID
## 16693 3331 2/2/2014 18:00      21.760         0         0    Earth
## 16694 3332 2/2/2014 20:00      21.760         0         0    Earth
## 16695 3333 2/2/2014 22:00      21.760         0         0    Earth
## 16696 3334  2/3/2014 0:00      21.664         0         0    Earth
## 16697 3335  2/3/2014 2:00      21.664         0         0    Earth
## 16698 3336  2/3/2014 4:00      21.664         0         0    Earth
## 16699 3337  2/3/2014 6:00      21.664         0         0    Earth
## 16700 3338  2/3/2014 8:00      21.569         0         0    Earth
## 16701 3339 2/3/2014 10:00      21.664         0         0    Earth
## 16702 3340 2/3/2014 12:00      21.760         0         0    Earth

separate hours from the date column

## separate date from hours and minutes
t.str <- strptime(data.hobo[,"Date"], "%m/%d/%Y %H:%M") ## format is month/day/year hour:minute
data.hobo[,"days"] <- as.Date(format(t.str, "%m/%d/%Y"), "%m/%d/%Y") ## separate date
data.hobo[,"hours"] <- as.numeric(format(t.str, "%H")) ##specify hour logged
data.hobo[,"minutes"] <- as.numeric(format(t.str, "%M")) ## specify minutes logged
head(data.hobo, 10)
##    ID            Date Temperature Avg.light Max.light      loggerID
## 1   1 4/19/2013 12:00      25.708      43.1      43.1 Allan_Laroque
## 2   2 4/19/2013 14:00      25.125       0.0       0.0 Allan_Laroque
## 3   3 4/19/2013 16:00      19.853       0.0       0.0 Allan_Laroque
## 4   4 4/19/2013 18:00      17.950       0.0       0.0 Allan_Laroque
## 5   5 4/19/2013 20:00      15.282       0.0       0.0 Allan_Laroque
## 6   6 4/19/2013 22:00      12.690       0.0       0.0 Allan_Laroque
## 7   7  4/20/2013 0:00      10.748       0.0       0.0 Allan_Laroque
## 8   8  4/20/2013 2:00       9.275       0.0       0.0 Allan_Laroque
## 9   9  4/20/2013 4:00       7.882       0.0       0.0 Allan_Laroque
## 10 10  4/20/2013 6:00       6.268       0.0       0.0 Allan_Laroque
##          days hours minutes
## 1  2013-04-19    12       0
## 2  2013-04-19    14       0
## 3  2013-04-19    16       0
## 4  2013-04-19    18       0
## 5  2013-04-19    20       0
## 6  2013-04-19    22       0
## 7  2013-04-20     0       0
## 8  2013-04-20     2       0
## 9  2013-04-20     4       0
## 10 2013-04-20     6       0

extracting specific statistics

library(dplyr)
## extract mean and standard error for loggers and hour of day
data.hourly <- data.hobo %>% group_by(loggerID, hours)  %>%  summarise(Temp=mean(Temperature),Light=mean(Avg.light),Temp.se=se(Temperature),Light.se=se(Avg.light))
data.hourly <- data.frame(data.hourly)

data.hourly
##         loggerID hours     Temp        Light   Temp.se     Light.se
## 1  Allan_Laroque     0 16.33226 3.884892e-02 0.3648513 3.884892e-02
## 2  Allan_Laroque     2 15.86632 0.000000e+00 0.3752375 0.000000e+00
## 3  Allan_Laroque     4 15.44694 0.000000e+00 0.3849025 0.000000e+00
## 4  Allan_Laroque     6 15.42670 1.035509e+03 0.3840829 1.158282e+02
## 5  Allan_Laroque     8 17.51994 8.193466e+03 0.3896634 1.046830e+03
## 6  Allan_Laroque    10 19.05345 6.918788e+03 0.3666236 7.941028e+02
## 7  Allan_Laroque    12 19.95085 1.315911e+04 0.3598451 2.255564e+03
## 8  Allan_Laroque    14 20.26105 1.110597e+04 0.3368601 1.783322e+03
## 9  Allan_Laroque    16 19.85099 4.849492e+03 0.3267292 8.117319e+02
## 10 Allan_Laroque    18 18.57063 9.511272e+02 0.3410991 1.095592e+02
## 11 Allan_Laroque    20 17.54351 9.992473e+00 0.3513072 1.811262e+00
## 12 Allan_Laroque    22 16.86679 0.000000e+00 0.3561886 0.000000e+00
## 13        Carrot     0 16.82263 0.000000e+00 0.3622150 0.000000e+00
## 14        Carrot     2 16.20739 0.000000e+00 0.3727668 0.000000e+00
## 15        Carrot     4 15.72073 0.000000e+00 0.3851332 0.000000e+00
## 16        Carrot     6 15.39554 4.072953e+02 0.3877566 4.555910e+01
## 17        Carrot     8 17.65499 1.310946e+04 0.4035867 1.066235e+03
## 18        Carrot    10 21.73332 5.327072e+04 0.4408048 3.547341e+03
## 19        Carrot    12 23.18673 2.713123e+04 0.4373945 2.109609e+03
## 20        Carrot    14 24.80014 6.050654e+04 0.4707862 4.144713e+03
## 21        Carrot    16 24.91188 5.148824e+04 0.4913177 3.335912e+03
## 22        Carrot    18 22.74586 2.203049e+04 0.4549085 1.559317e+03
## 23        Carrot    20 19.01715 2.271777e+03 0.3710476 2.328386e+02
## 24        Carrot    22 17.49219 0.000000e+00 0.3588345 0.000000e+00
## 25  Charles_Sule     0 16.98273 3.884892e-02 0.3451947 3.884892e-02
## 26  Charles_Sule     2 16.38139 0.000000e+00 0.3580559 0.000000e+00
## 27  Charles_Sule     4 15.91030 0.000000e+00 0.3678661 0.000000e+00
## 28  Charles_Sule     6 15.56310 4.616161e+02 0.3711982 5.125079e+01
## 29  Charles_Sule     8 18.76927 2.459781e+04 0.4245105 2.024230e+03
## 30  Charles_Sule    10 23.88400 6.695851e+04 0.4296541 3.850388e+03
## 31  Charles_Sule    12 25.63530 8.205698e+04 0.4626615 4.594056e+03
## 32  Charles_Sule    14 25.11787 6.741514e+04 0.4445177 3.928814e+03
## 33  Charles_Sule    16 23.88458 3.885798e+04 0.4344474 2.359570e+03
## 34  Charles_Sule    18 20.91928 1.122824e+04 0.3769713 8.146276e+02
## 35  Charles_Sule    20 18.61054 1.743957e+03 0.3478528 1.532019e+02
## 36  Charles_Sule    22 17.58751 3.884892e-02 0.3423564 3.884892e-02
## 37   Doro_ground     0 19.19254 0.000000e+00 0.2579197 0.000000e+00
## 38   Doro_ground     2 18.76200 0.000000e+00 0.2717691 0.000000e+00
## 39   Doro_ground     4 18.37085 0.000000e+00 0.2895689 0.000000e+00
## 40   Doro_ground     6 18.03445 1.906283e+02 0.3023740 2.108784e+01
## 41   Doro_ground     8 19.23100 4.393700e+03 0.2500331 3.397543e+02
## 42   Doro_ground    10 24.11629 3.466917e+04 0.3552740 2.782418e+03
## 43   Doro_ground    12 26.68005 5.174972e+04 0.4648171 4.189968e+03
## 44   Doro_ground    14 27.14960 5.277906e+04 0.4784872 4.403371e+03
## 45   Doro_ground    16 26.48112 3.752684e+04 0.4189941 3.105100e+03
## 46   Doro_ground    18 21.98922 3.864414e+03 0.2121463 3.016734e+02
## 47   Doro_ground    20 20.72215 7.474730e+02 0.2229716 6.883104e+01
## 48   Doro_ground    22 19.73769 0.000000e+00 0.2393931 0.000000e+00
## 49         Earth     0 15.43738 0.000000e+00 0.4116454 0.000000e+00
## 50         Earth     2 14.81946 0.000000e+00 0.4223876 0.000000e+00
## 51         Earth     4 14.27596 0.000000e+00 0.4349312 0.000000e+00
## 52         Earth     6 14.00567 3.029344e+02 0.4369798 3.816488e+01
## 53         Earth     8 17.29656 1.246227e+04 0.4485807 1.011235e+03
## 54         Earth    10 22.37986 4.079136e+04 0.4748383 2.735017e+03
## 55         Earth    12 24.27305 4.806232e+04 0.4794273 3.432302e+03
## 56         Earth    14 24.48792 4.491603e+04 0.4293910 3.514977e+03
## 57         Earth    16 24.93144 5.563345e+04 0.4678822 4.189199e+03
## 58         Earth    18 23.24071 3.521375e+04 0.4964829 2.988325e+03
## 59         Earth    20 18.34003 1.821471e+03 0.4027971 1.776731e+02
## 60         Earth    22 16.35201 0.000000e+00 0.4031816 0.000000e+00

plot

## select one logger to plot
Carrot.logger <- subset(data.hourly, loggerID=="Carrot")
par(mfrow=c(1,2)) ## side by side plots

## plot the light radiation on average for each hour of the day during the season
plot(Carrot.logger[,"hours"],Carrot.logger[,"Light"], pch=21, bg="White", ylab="Light (lux)", xlab="hour of the day", ylim=c(0,65000))
error.bar(Carrot.logger[,"hours"],Carrot.logger[,"Light"],Carrot.logger[,"Light.se"])
points(Carrot.logger[,"hours"],Carrot.logger[,"Light"], pch=21, bg="White") ## repeat to cover lines

## plot the temperature on average for each hour of the day during the season
plot(Carrot.logger[,"hours"],Carrot.logger[,"Temp"], pch=21, bg="Black", ylab="Temperature (C°)", xlab="hour of the day", ylim=c(12,28))
error.bar(Carrot.logger[,"hours"],Carrot.logger[,"Temp"],Carrot.logger[,"Temp.se"])

selecting for time frames

## subset for mid day temperatures and light
mid.day <- subset(data.hobo, hours < 16 & hours > 8) #between 10-14
##summarize mid day values
mid.day.means <- mid.day %>% group_by(loggerID)  %>%  summarise(Temp=mean(Temperature),Light=mean(Avg.light),Temp.se=se(Temperature),Light.se=se(Avg.light))
mid.day.means <- data.frame(mid.day.means)
mid.day.means
##        loggerID     Temp    Light   Temp.se  Light.se
## 1 Allan_Laroque 19.75596 10398.78 0.2052735  998.1355
## 2        Carrot 23.23820 46953.31 0.2630108 2008.4484
## 3  Charles_Sule 24.87877 72149.20 0.2583407 2398.7491
## 4   Doro_ground 25.98058 46391.69 0.2557650 2243.3120
## 5         Earth 23.71269 44589.51 0.2683382 1874.4801