我正在分析一个复杂数据集中的时间模式,其中包括多个环境变量以及来自各种动物物种的活动数据。这些数据由多个实验设置收集,并且每个设置的数据每分钟存储一次。该项目已经运行了几年,因此我的数据集相当大。
我的一个数据集的前几行如下所示:
到目前为止一切都很好......使用
除了丑陋和缓慢,这段代码还有一个大问题:它不能处理缺失值。有时由于设备故障,数据在几个小时或几天内根本没有记录。如果在日落期间没有记录任何数据,则上述代码不会增加天数计数器。这意味着我需要 - 在某种程度上 - 同时纳入日期/时间代码。很容易创建一个从实验开始以来的天数变量:
也许这些数字可以被使用,可能与Heroka's的好的
我已经使用
我一直在寻找更好、更漂亮、特别是更快的东西,但一直无法想出一个好的技巧。我试图调整我的数据框的子集,但得出结论这可能是一个愚蠢的方法。我看过
我的一个数据集的前几行如下所示:
> 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
循环的方式,这不是一个好的方法。另外,考虑到我已经收集了超过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")))
也许这些数字可以被使用,可能与Heroka's的好的
rle
算法相结合。我已经使用
dput
从一个设置中制作了几个月的数据,包括一些大块丢失的数据,以及新创建的变量(如本帖子和Heroka's的答案所述),可在here找到。我一直在寻找更好、更漂亮、特别是更快的东西,但一直无法想出一个好的技巧。我试图调整我的数据框的子集,但得出结论这可能是一个愚蠢的方法。我看过
maptools
、lubridate
和GeoLight
。我搜索了Google、Stack Overflow和各种书籍,比如Hadley Wickham的精彩Advanced R。但都没有找到。也许我错过了一些显而易见的东西。我希望这里有人能帮助我。
dput
提供。 - Yuri Robbers