我正在分析一个复杂数据集中的时间模式,该数据集中包含几个环境变量以及来自各种动物物种的活动数据。这些数据由多个实验装置收集,每个装置的数据每分钟存储一次。该项目已经运行了几年,所以我的数据集相当大。
我的一个数据集的前几行如下所示:
> head(setup_01)
DateTime Film_number unused PIR Wheel Temperature LightOld LightDay LightNight LightUV IDnumbers error mouse shrew vole rat frog rest extra_info odour
1 2015-03-10 12:27:10 x 0 0 13.40 1471.34 -0.97 1331.29 700.42 no error 0 0 0 0 0 0 1
2 2015-03-10 12:28:10 x 0 0 13.43 1471.38 -1.07 1291.11 731.32 no error 0 0 0 0 0 0 1
3 2015-03-10 12:29:10 x 0 0 13.31 1471.24 -1.08 1368.57 1016.02 no error 0 0 0 0 0 0 1
因为我想将这些变量与整个季节的日出和日落等各种自然周期联系起来,所以我使用了这个包maptools
来计算日出和日落时间
library(maptools)
gpclibPermit()
#set coordinates
crds=c(4.4900,52.1610)
# download the sunrise/sunset/etc data
setup_01$sunrise=sunriset(matrix(crds,nrow=1),dateTime=as.POSIXct(setup_01$DateTime),POSIXct.out=TRUE,direction="sunrise")
setup_01$sunset=sunriset(matrix(crds,nrow=1),dateTime=as.POSIXct(setup_01$DateTime),POSIXct.out=TRUE,direction="sunset")
#create a variable that's 0 except at sunrise, and one that's 0 except at sunset
setup_01$sunrise_act=0
setup_01$sunset_act=0
setup_01[abs(unclass(setup_01[,"DateTime"])-unclass(setup_01[,"sunrise"]$time))<30,]$sunrise_act=1
setup_01[abs(unclass(setup_01[,"DateTime"])-unclass(setup_01[,"sunset"]$time))<30,]$sunset_act=1
由于大多数动物的行为不同,这取决于它是白天还是晚上,我使用日落/日出时间来计算数据来计算一个新变量,它在晚上为 0,在白天为 1:
#create a variable that's 0 at night and 1 at daytime
setup_01$daytime=0
setup_01[setup_01[,"DateTime"]>setup_01[,"sunrise"]$time & setup_01[,"DateTime"]<setup_01[,"sunset"]$time,]$daytime=1
到目前为止,一切都很好......甚至可以maptools
使用民用/航海/天文黄昏和黎明的开始而不是日出和日落。
然而,这就是我的问题开始的地方。我想对实验中的所有日子进行编号。而不是像往常一样在午夜增加日计数器,而且很容易做,我想在日落时增加日计数器(或者可能在未来的实验中另一个可移动的时间,如日出,航海黄昏和黎明,......) . 由于日落并非每天都在同一时间发生,所以对我来说,这不是一个简单的问题要解决。
我只提出了一个for
-loop,这不是一种很好的做事方式。此外,考虑到我在几个设置中每分钟收集一次价值超过 6 年的数据点,我可以坐下来观察构造板块的移动,而 R 会通过这样的一大堆循环:
setup_01$day=0
day<-1
for(i in 1:nrow(setup_01)){
setup_01[i,]$day<-day
if(setup_01[i,]$sunset_act==1){
day<-day+1
}
}
除了丑陋和缓慢之外,这段代码还有一个大问题:它不处理缺失值。有时,由于设备故障,数小时或数天都没有记录数据。如果在日落期间没有记录数据,则上述代码不会增加日计数器。这意味着我还需要 - 以某种方式 - 合并日期/时间代码。很容易创建自实验开始以来的天数变量:
setup_01$daynumber<-as.integer(ceiling(difftime(setup_01$DateTime, setup_01$DateTime[1], units = "days")))
也许可以使用这些数字,可能与Herka 的nice rle
-algorithm 结合使用。
我曾经dput
从一个设置中获取几个月的数据,包括几大块缺失的数据,以及新创建的变量(如本文和Herka 的回答中所述)可在此处获得。
我一直在寻找更好,更好,尤其是更快的东西,但一直无法想出一个好的技巧。我摆弄了我的数据框的子集,但得出的结论是这可能是一种愚蠢的方法。我看过maptools
,lubridate
和GeoLight
. 我搜索了 Google、Stack Overflow 和各种书籍,比如 Hadley Wickham 的出色的Advanced R。一切都无济于事。也许我错过了一些明显的东西。我希望这里有人可以帮助我。