R:按时间间隔拆分观察值并将其聚合到时间间隔

R:按时间间隔拆分观察值并将其聚合到时间间隔,r,time,intervals,R,Time,Intervals,在某些地区(名称)的不同观测点(obs)都有鸟类观测。采用了开始和结束时间,并使用校正系数重新计算了时差(diff_corr),因此它不仅仅是开始-结束间隔的difftime 现在,我需要将这些值“拆分”为“良好”间隔(15分钟,例如10:15:00、10:30:00,…),然后按面积进行聚合(name),以便能够在这些干净的15分钟间隔内绘制出这些区域上鸟类的分布图 所以,让它更清楚一点:一个观测可能从10:14开始,一直持续到10:25,所以它跨越了10:00-10:15和10:15-10:

在某些地区(名称)的不同观测点(obs)都有鸟类观测。采用了开始结束时间,并使用校正系数重新计算了时差(diff_corr),因此它不仅仅是开始-结束间隔的
difftime

现在,我需要将这些值“拆分”为“良好”间隔(15分钟,例如10:15:00、10:30:00,…),然后按面积进行聚合(name),以便能够在这些干净的15分钟间隔内绘制出这些区域上鸟类的分布图

所以,让它更清楚一点:一个观测可能从10:14开始,一直持续到10:25,所以它跨越了10:00-10:15和10:15-10:30的间隔,所以我得到的值应该被分割,并根据它们在该间隔中的部分相应地分配给适当的间隔

在更复杂的设置中,一个观测值可能跨越3或4个间隔,因此该值也必须相应地拆分

最后一步是将每个间隔的所有观察部分汇总并绘制它们

我已经搜索了几天的解决方案,但只找到了非常简单的示例,其中间隔用
cut
breaks
重新排列,但没有示例如何处理相关值,而是简单的频率计数

示例数据:

structure(list(obs = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("b", 
"C2", "Dürnberg2"), class = "factor"), name = c("C2", "C2", 
"C2", "C2", "C2", "C2", "C2", "C2", "C2", "b", "981", "1627", 
"b", "b", "981", "1627", "b", "b", "b", "b"), start = structure(c(1495441500, 
1495441590, 1495441650, 1495441680, 1495447380, 1495447410, 1495447530, 
1495447560, 1495447580, 1496996580, 1496996580, 1496996580, 1496996760, 
1496996820, 1496996820, 1496996820, 1496997180, 1496997300, 1496997420, 
1496998260), class = c("POSIXct", "POSIXt"), tzone = ""), end = structure(c(1495441590, 
1495441650, 1495441680, 1495441800, 1495447410, 1495447530, 1495447560, 
1495447580, 1495447620, 1496996760, 1496996760, 1496996760, 1496996820, 
1496997180, 1496997180, 1496997180, 1496997300, 1496997420, 1496997540, 
1496998320), class = c("POSIXct", "POSIXt"), tzone = ""), diff_corr = c(1.46739130434783, 
0.978260869565217, 0.489130434782609, 1.95652173913043, 0.489130434782609, 
1.95652173913043, 0.489130434782609, 0.326086956521739, 0.652173913043478, 
2.96703296703297, 2.96703296703297, 2.96703296703297, 0.989010989010989, 
5.93406593406593, 5.93406593406593, 5.93406593406593, 1.97802197802198, 
1.97802197802198, 1.97802197802198, 0.989010989010989)), .Names = c("obs", 
"name", "start", "end", "diff_corr"), row.names = c("1", "9", 
"7", "8", "3", "2", "4", "5", "6", "13", "13.1", "13.2", "22", 
"11", "11.1", "11.2", "12", "23", "15", "16"), class = "data.frame")
p、 我真的很难恰当地说出我的问题,所以任何提示(不仅仅是关于这个)都非常感谢

一个小例子的新尝试: 将值按比例分配给间隔(然后将相等间隔相加)


这是缓慢和笨重的,但可能是有益的。按名称和15分钟间隔计算计数和加权差值和:

library(dplyr)
range <- seq.POSIXt(min(df$start)-(15*60), max(df$end)+(15*60), by = "15 min")

df$totalDuration <- as.numeric(as.difftime(df$end-df$start),units=c("secs"))

out <- NULL
for (r in 1:length(range)){
  subset <- df %>% filter( (start >= (range[r]-(15*60)) & start<range[r]) |
                             (end>= (range[r]-(15*60)) & end<range[r] ) |
                             (end > range[r] & start < range[r])) %>%
    mutate(bin=range[r],
           duration = ifelse(start>=(range[r]-(15*60)) & end<range[r],totalDuration,
                        ifelse(start>=(range[r]-(15*60)),as.numeric(as.difftime(range[r]-start),units="secs"),
                          ifelse(end<range[r],
                                 as.numeric(as.difftime(end-(range[r]-(15*60))),units="secs"),
                                            as.numeric(as.difftime(range[r]-(range[r]-(15*60))),units="secs")
                        )))
           ) %>% 
    mutate (diff_corr_W = diff_corr*(duration/as.double(totalDuration, units='secs'))) %>%
    group_by(bin,name) %>% summarise(count=n(),
                                     diff_corr_sum = sum(diff_corr_W)) %>% ungroup()


  if (is.null(out)){
    out <- subset
  } else {
    out <- rbind(out,subset)
  }
}


> out
# A tibble: 9 x 4
bin  name count diff_corr_sum
*              <dttm> <chr> <int>         <dbl>
  1 2017-05-22 04:40:00    C2     4      4.891304
2 2017-05-22 06:10:00    C2     5      3.913043
3 2017-06-09 04:25:00  1627     1      1.978022
4 2017-06-09 04:25:00   981     1      1.978022
5 2017-06-09 04:25:00     b     1      1.978022
6 2017-06-09 04:40:00  1627     2      6.923077
7 2017-06-09 04:40:00   981     2      6.923077
8 2017-06-09 04:40:00     b     6     13.846154
9 2017-06-09 04:55:00     b     1      0.989011
库(dplyr)
range=(range[r]-(15*60))&end=(range[r]-(15*60)),as.numeric(as.difftime(range[r]-start),units=“secs”),
如果其他(结束%
变异(diff_corr_W=diff_corr*(持续时间/as.double(totalDuration,units='secs')))%>%
分组依据(bin,name)%>%汇总(count=n(),
diff_corr_sum=sum(diff_corr_W))%>%ungroup()
if(is.null(out)){

out这是一个缓慢而笨拙的过程,但可能会有所帮助。按名称和15分钟间隔计算计数和加权差值和:

library(dplyr)
range <- seq.POSIXt(min(df$start)-(15*60), max(df$end)+(15*60), by = "15 min")

df$totalDuration <- as.numeric(as.difftime(df$end-df$start),units=c("secs"))

out <- NULL
for (r in 1:length(range)){
  subset <- df %>% filter( (start >= (range[r]-(15*60)) & start<range[r]) |
                             (end>= (range[r]-(15*60)) & end<range[r] ) |
                             (end > range[r] & start < range[r])) %>%
    mutate(bin=range[r],
           duration = ifelse(start>=(range[r]-(15*60)) & end<range[r],totalDuration,
                        ifelse(start>=(range[r]-(15*60)),as.numeric(as.difftime(range[r]-start),units="secs"),
                          ifelse(end<range[r],
                                 as.numeric(as.difftime(end-(range[r]-(15*60))),units="secs"),
                                            as.numeric(as.difftime(range[r]-(range[r]-(15*60))),units="secs")
                        )))
           ) %>% 
    mutate (diff_corr_W = diff_corr*(duration/as.double(totalDuration, units='secs'))) %>%
    group_by(bin,name) %>% summarise(count=n(),
                                     diff_corr_sum = sum(diff_corr_W)) %>% ungroup()


  if (is.null(out)){
    out <- subset
  } else {
    out <- rbind(out,subset)
  }
}


> out
# A tibble: 9 x 4
bin  name count diff_corr_sum
*              <dttm> <chr> <int>         <dbl>
  1 2017-05-22 04:40:00    C2     4      4.891304
2 2017-05-22 06:10:00    C2     5      3.913043
3 2017-06-09 04:25:00  1627     1      1.978022
4 2017-06-09 04:25:00   981     1      1.978022
5 2017-06-09 04:25:00     b     1      1.978022
6 2017-06-09 04:40:00  1627     2      6.923077
7 2017-06-09 04:40:00   981     2      6.923077
8 2017-06-09 04:40:00     b     6     13.846154
9 2017-06-09 04:55:00     b     1      0.989011
库(dplyr)
range=(range[r]-(15*60))&end=(range[r]-(15*60)),as.numeric(as.difftime(range[r]-start),units=“secs”),
如果其他(结束%
变异(diff_corr_W=diff_corr*(持续时间/as.double(totalDuration,units='secs')))%>%
分组依据(bin,name)%>%汇总(count=n(),
diff_corr_sum=sum(diff_corr_W))%>%ungroup()
if(is.null(out)){

out这里有一个
data.table
方法,它允许您使用SQL类型的查询对数据进行排序/筛选并执行操作

数据

> p
    obs name               start                 end diff_corr
 1:  C2   C2 2017-05-22 04:25:00 2017-05-22 04:26:30 1.4673913
 2:  C2   C2 2017-05-22 04:26:30 2017-05-22 04:27:30 0.9782609
 3:  C2   C2 2017-05-22 04:27:30 2017-05-22 04:28:00 0.4891304
 4:  C2   C2 2017-05-22 04:28:00 2017-05-22 04:30:00 1.9565217
 5:  C2   C2 2017-05-22 06:03:00 2017-05-22 06:03:30 0.4891304
 6:  C2   C2 2017-05-22 06:03:30 2017-05-22 06:05:30 1.9565217
 7:  C2   C2 2017-05-22 06:05:30 2017-05-22 06:06:00 0.4891304
 8:  C2   C2 2017-05-22 06:06:00 2017-05-22 06:06:20 0.3260870
 9:  C2   C2 2017-05-22 06:06:20 2017-05-22 06:07:00 0.6521739
10:   b    b 2017-06-09 04:23:00 2017-06-09 04:26:00 2.9670330
11:   b  981 2017-06-09 04:23:00 2017-06-09 04:26:00 2.9670330
12:   b 1627 2017-06-09 04:23:00 2017-06-09 04:26:00 2.9670330
13:   b    b 2017-06-09 04:26:00 2017-06-09 04:27:00 0.9890110
14:   b    b 2017-06-09 04:27:00 2017-06-09 04:33:00 5.9340659
15:   b  981 2017-06-09 04:27:00 2017-06-09 04:33:00 5.9340659
16:   b 1627 2017-06-09 04:27:00 2017-06-09 04:33:00 5.9340659
17:   b    b 2017-06-09 04:33:00 2017-06-09 04:35:00 1.9780220
18:   b    b 2017-06-09 04:35:00 2017-06-09 04:37:00 1.9780220
19:   b    b 2017-06-09 04:37:00 2017-06-09 04:39:00 1.9780220
20:   b    b 2017-06-09 04:51:00 2017-06-09 04:52:00 0.9890110
代码

library(data.table)
library(lubridate)
p <- as.data.table(p)
p[, .(new_diff = mean(diff_corr)), .(tme_start = round_date(start, unit = "15min"))]
数据表在做什么?

由于您不熟悉
data.table
,下面是对正在发生的事情的快速、基本的描述。
data.table
调用的一般形式是:

DT[select rows, perform operations, group by] 
其中,
DT
数据表
名称。
选择行
是一种逻辑操作,例如,假设您只需要对C2(名称)进行观察,调用将是
DT[name==“C2”,]
不需要执行任何操作,也不需要分组。如果您想要所有
名称==“C2”
,调用变为
DT[name==“C2”,list(sum(diff_corr))]
。您可以使用
)来代替编写
list()
。现在,当
name==“C2”时,输出将只有一行和一列名为
V1
,这是所有
diff_corr
的总和“
。该列没有太多信息,因此我们为其指定了一个名称(可以与旧的名称相同):
DT[name==“C2”,(diff_corr_sum=sum(diff_corr))]
。假设您有另一个名为“mood”的列,其中报告了进行观察的人的情绪,并可以假设三个值(“高兴”、“悲伤”、“困倦”)。您可以按语气“分组:
DT[name==“C2”,(diff_corr\u new=sum(diff_corr)),按=.(mood)]
。输出将是与每个情绪对应的三行和一列
diff\u corr\u new
。要更好地理解这一点,请尝试使用类似
mtcars
的示例数据集。您的示例数据没有足够的复杂性等,无法让您探索所有这些函数

返回答案-其他变体

从问题或注释中不清楚您是否要根据
开始
结束
进行取整。我使用了前者,但您可以更改。上面的示例使用
平均值
,但您可以执行可能需要的任何其他操作。其他列似乎或多或少是冗余的,因为它们是字符串,您无法执行太多操作使用它们。您可以使用它们在
by
条目(代码中的最后一个字段)中对结果进行进一步排序。下面是分别使用
obs
name
的两个示例。您也可以将它们组合在一起

> p[, .(new_diff = mean(diff_corr)), .(tme_start = round_date(start, unit = "15min"), obs)]
             tme_start obs  new_diff
1: 2017-05-22 04:30:00  C2 1.2228261
2: 2017-05-22 06:00:00  C2 0.7826087
3: 2017-06-09 04:30:00   b 3.3626374
4: 2017-06-09 04:45:00   b 0.9890110


> p[, .(new_diff = mean(diff_corr)), .(tme_start = round_date(start, unit = "15min"), name)]
             tme_start name  new_diff
1: 2017-05-22 04:30:00   C2 1.2228261
2: 2017-05-22 06:00:00   C2 0.7826087
3: 2017-06-09 04:30:00    b 2.6373626
4: 2017-06-09 04:30:00  981 4.4505495
5: 2017-06-09 04:30:00 1627 4.4505495
6: 2017-06-09 04:45:00    b 0.9890110

下面是一种
data.table
方法,它允许您使用SQL类型的查询对数据进行排序/筛选并执行操作

数据

> p
    obs name               start                 end diff_corr
 1:  C2   C2 2017-05-22 04:25:00 2017-05-22 04:26:30 1.4673913
 2:  C2   C2 2017-05-22 04:26:30 2017-05-22 04:27:30 0.9782609
 3:  C2   C2 2017-05-22 04:27:30 2017-05-22 04:28:00 0.4891304
 4:  C2   C2 2017-05-22 04:28:00 2017-05-22 04:30:00 1.9565217
 5:  C2   C2 2017-05-22 06:03:00 2017-05-22 06:03:30 0.4891304
 6:  C2   C2 2017-05-22 06:03:30 2017-05-22 06:05:30 1.9565217
 7:  C2   C2 2017-05-22 06:05:30 2017-05-22 06:06:00 0.4891304
 8:  C2   C2 2017-05-22 06:06:00 2017-05-22 06:06:20 0.3260870
 9:  C2   C2 2017-05-22 06:06:20 2017-05-22 06:07:00 0.6521739
10:   b    b 2017-06-09 04:23:00 2017-06-09 04:26:00 2.9670330
11:   b  981 2017-06-09 04:23:00 2017-06-09 04:26:00 2.9670330
12:   b 1627 2017-06-09 04:23:00 2017-06-09 04:26:00 2.9670330
13:   b    b 2017-06-09 04:26:00 2017-06-09 04:27:00 0.9890110
14:   b    b 2017-06-09 04:27:00 2017-06-09 04:33:00 5.9340659
15:   b  981 2017-06-09 04:27:00 2017-06-09 04:33:00 5.9340659
16:   b 1627 2017-06-09 04:27:00 2017-06-09 04:33:00 5.9340659
17:   b    b 2017-06-09 04:33:00 2017-06-09 04:35:00 1.9780220
18:   b    b 2017-06-09 04:35:00 2017-06-09 04:37:00 1.9780220
19:   b    b 2017-06-09 04:37:00 2017-06-09 04:39:00 1.9780220
20:   b    b 2017-06-09 04:51:00 2017-06-09 04:52:00 0.9890110
代码

library(data.table)
library(lubridate)
p <- as.data.table(p)
p[, .(new_diff = mean(diff_corr)), .(tme_start = round_date(start, unit = "15min"))]
数据表在做什么?

由于您不熟悉
data.table
,下面是对正在发生的事情的快速、基本的描述。
data.table
调用的一般形式是:

DT[select rows, perform operations, group by] 
其中,
DT
数据表
名称。
选择行
是一种逻辑操作,例如,假设您只希望对C2(名称)进行观察,则调用将是
DT[name==“C2”,]
没有操作r