R:计算从日落开始的天数

标签 r datetime time-series lubridate maptools

我正在分析一个复杂数据集中的时间模式,该数据集中包含多个环境变量以及来自各种动物物种的事件数据。这些数据由多个实验设置收集,每个设置的数据每分钟存储一次。这个项目已经运行了好几年了,所以我的数据集相当大。

我的一个数据集的前几行如下所示:

> 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使用民用/航海/天文黄昏和黎明的开始,而不是日出和日落。

然而,这就是我的问题开始的地方。我想在我的实验中计算所有的日子。而不是像往常一样容易在午夜增加日计数器,我想在日落时增加日计数器(或者可能在 future 的实验中增加一天中另一个可移动的时间,如日出、航海黄昏和黎明,......) .由于日落并非每天都在同一时间发生,因此对我来说,这不是一个直接需要解决的问题。

我只是想出了一个 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")))

也许可以使用这些数字,可能与 Heroka's 一起使用不错rle -算法。

我用过 dput从一个设置中获取几个月的数据,包括几大块丢失的数据,以及新创建的变量(如本文和 Heroka's 答案中所述)可用 here .

我一直在寻找更好、更好、特别是更快的东西,但一直无法想出一个好技巧。我已经摆弄了我的数据框的子集,但得出的结论是这可能是一种愚蠢的方法。我看过 maptools , lubridate , 和 GeoLight .我搜索过谷歌、Stack Overflow 和各种书籍,比如 Hadley Wickham 出色的 Advanced R。都无济于事。也许我错过了一些明显的东西。我希望这里有人可以帮助我。

最佳答案

我想出了一个关于生成的 0 和 1 的解决方案(因为您已经生成了它们),并且它适用于运行长度。

  #sunset/sunrise is series of 0's and 1's indicating night and daytime, so solution that works for random sequence
#will work for OP's dataset
set.seed(10)
sunset <- c(1,rbinom(20,1,0.5))

#counter needs to be x for sequence of 11111 (day) and 0000(night), and then increase when 0 reappears
#counter starts at 1

#intermediate step: number each half-day
rle_sunset <- rle(sunset)
period <- rep(1:length(rle_sunset$lengths),rle_sunset$lengths)
#calculate day so that each two subsequent periods are one day

day <- ceiling(period/2)

> cbind(sunset,period,day)
      sunset period day
 [1,]      1      1   1
 [2,]      1      1   1
 [3,]      0      2   1
 [4,]      0      2   1
 [5,]      1      3   2
 [6,]      0      4   2
 [7,]      0      4   2
 [8,]      0      4   2
 [9,]      0      4   2
[10,]      1      5   3
[11,]      0      6   3
[12,]      1      7   4
[13,]      1      7   4
[14,]      0      8   4
[15,]      1      9   5
[16,]      0     10   5
[17,]      0     10   5
[18,]      0     10   5
[19,]      0     10   5
[20,]      0     10   5
[21,]      1     11   6

关于R:计算从日落开始的天数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31941727/

相关文章:

r - 在 Gadfly 中使用对数刻度调整刻度间距

java - H2 中的 DATETIME 值与从 Java/Kotlin 插入的 MySQL 数据库之间的不匹配

java - 同时将多个数据推送到 influxdb 时丢失数据。?

javascript - 按日期对 Trello 卡片数组进行排序

mysql - 查看[时间长度]是否可用于多行预订的最佳方法是什么?

r - 使用 R 的 SARIMAX 模型的数值方法

对不规则时间序列进行定期分析

r - 行中的条件标记

r - 增加图例中边框的线宽

r - R 中的 CVX 式凸优化?