【问题标题】:How to select rows with times separated by a certain interval in R如何在R中选择时间间隔一定间隔的行
【发布时间】:2018-08-15 15:05:04
【问题描述】:

我有一个大型数据框,其中包含每个月放置在不同位置的相机陷阱的相机陷阱观察结果。一项观察由一只动物触发的五张照片组成。 Excerpt of the dataframe

前 20 行中的dput

>structure(list(deploymentid = structure(c(2L, 2L, 2L, 2L, 2L, 
>2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), .Label = c("B4-Wintergatter_Riedlhäng",
"I3-Wintergatter_Riedlhäng"), class = "factor"), species = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L), .Label = "Rotwild", class = "factor"), time = structure(c(1520900972, 
1520900972, 1520900972, 1520900972, 1520900972, 1520900982, 1520900982, 
1520900982, 1520900982, 1520900982, 1520901025, 1520901025, 1520901025, 
1520901025, 1520901025, 1520975705, 1520975705, 1520975705, 1520975705, 
1520975705), class = c("POSIXct", "POSIXt"), tzone = "UTC")), .Names = c("deploymentid", 
"species", "time"), row.names = c(NA, 20L), class = "data.frame")

为了分析,我已确定连续观察之间的 2 分钟时间段被认为是独立的。为了实现这一点,我计算了每个相机部署的两张连续照片之间的时间差。之后,我选择了差异大于两分钟的所有时间。然后我将数据框子集化为仅包含在这些选定时间拍摄的照片:

1) 首先,我使用 dplyr 计算到同一部署的上一张照片的时间间隔。对于每个部署的第一次观察,我随机选择 1000 作为大于 120 的数字,因此稍后将其包含在我的选择中。

library(dplyr)
deerobs_tbl<-tbl_df(Deerobs)
deerobs_gr<-group_by(deerobs_tbl,deploymentid)
deerobs_or<-arrange(deerobs_gr$time,.by_group = T)
deerobs_2<-mutate(deerobs_or,diff=c(1000,diff(time)))
deerobs2_df<-data.frame(deerobs_2)

2) 我想这也可以通过 dplyr 实现,但 plyr 更易于使用。我只构建了一个数据框,其中包含部署 ID、时间以及与上一张图片的时间差的列。然后,我为每个部署选择了相隔超过 2 分钟的时间,并选择了具有这些时间的所有行。

library (plyr)
deerobs_times<-data.frame(deerobs2_df$time,deerobs2_df$deploymentid,deerobs2_df$diff)
deerobs_times_apart<-ddply(deerobs_times,"deerobs2_df.deploymentid",subset,deerobs2_df.diff>120)
deerobs_t<-deerobs_times_apart[,1]
Deerobs_subset<-subset(deerobs2_df,deerobs2_df$time%in%deerobs_t)

唯一的问题是,这会删除比必要更多的观察结果。照片的数量从 9000 多张减少到 3000 多张。例如,如果 10 次观测以 1.5 分钟的间隔相互跟随,则所有照片都将被删除,尽管有 5 张彼此相距超过 2 分钟。有没有可能绕过这个问题,选择所有相隔两分钟以上的观察?

【问题讨论】:

  • 您可以改用dput 发布您的数据吗?无法从图像中抓取数据。
  • 我添加了一个指向包含数据的文件的链接,我希望它可以这样工作。
  • 您是否刚刚在 filedropper 上发布了指向您的数据的链接?请改用dput 发布您的数据。请阅读How to make a great R reproducible example? 寻求帮助。如果您想得到答案,您需要帮助我们帮助您。
  • 感谢您的帮助,希望这次我做对了。
  • 这是我从帖子中了解到的:如果数据有 10 个相隔 1 分钟的观测值,并且您发现连续观测值之间的时间差(使用 diff 等),那么所有这些观测值都是丢弃。但是,如果您要依次丢弃观察结果并每次重新计算时间差,则第三个观察结果的时间差将大于 2 分钟(与第一个观察结果相比,第二个观察结果被丢弃)并将被保留。是这样吗?

标签: r time


【解决方案1】:

如果您的数据集不是太大,聚类是解决此问题的一种方法。

library(dplyr)

data <- structure(list(deploymentid = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), .Label = c("B4-Wintergatter_Riedlhäng", "I3-Wintergatter_Riedlhäng"), class = "factor"), species = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "Rotwild", class = "factor"), time = structure(c(1520900972, 1520900972, 1520900972, 1520900972, 1520900972, 1520900982, 1520900982, 1520900982, 1520900982, 1520900982, 1520901025, 1520901025, 1520901025, 1520901025, 1520901025, 1520975705, 1520975705, 1520975705, 1520975705, 1520975705), class = c("POSIXct", "POSIXt"), tzone = "UTC")), .Names = c("deploymentid", "species", "time"), row.names = c(NA, 20L), class = "data.frame")

data %>%
  mutate(
    # Create a numeric vector on minute scale
    minutes    = difftime(time, min(time), units = 'min') %>% as.numeric(),
    # Cluster and group based on 2 minute height
    time_group = cutree(hclust(dist(minutes)), h = 2)
  ) %>%
  # Collapse the groups of images
  group_by(deploymentid, species, time_group) %>%
  summarise(n = n(), mean_time = mean(time))

# # A tibble: 3 x 5
# # Groups:   deploymentid, species [?]
#   deploymentid              species time_group     n mean_time          
#   <fct>                     <fct>        <int> <int> <dttm>             
# 1 B4-Wintergatter_Riedlhäng Rotwild          1     5 2018-03-13 00:30:25
# 2 I3-Wintergatter_Riedlhäng Rotwild          1    10 2018-03-13 00:29:37
# 3 I3-Wintergatter_Riedlhäng Rotwild          2     5 2018-03-13 21:15:05

【讨论】:

  • 非常感谢您的回答,尽管这不是我想要的。最后,您可以在每次部署时以两分钟为一组获得图片。我需要的是保留属于一个观察的所有五张图片(发生在 1 秒内),但如果它发生在至少 2 分钟后,则仅在同一部署期间选择下一个观察。
  • @biomaik 然后集群两次。一次将“图片”分组(1 秒),然后再将“观察”分组(2 分钟)。然后,您可以丢弃分配给同一观察的图片集群。
【解决方案2】:

感谢@Eric,您的想法对我解决问题有很大帮助。 所以最后的结果是这样的:

# Add a column "eventid", which is unique for each event
   Deerobs$eventid<-as.factor(paste(Deerobs$Kamera_ID,Deerobs$time,sep='-'))

# Group the pictures by deployment and order them 
  library(dplyr)
  deerobs_tbl<-tbl_df(Deerobs)
  deerobs_gr<-group_by(deerobs_tbl,deploymentid)
  deerobs_or<-arrange(deerobs_gr,deerobs_gr$time,.by_group = T)

# Add two minute time groups for each deployment
  deerobs2<-deerobs_or%>%mutate(
  minu=difftime(time, min(time), units = 'min') %>% as.numeric(),
  time_group_minu = cutree(hclust(dist(minu)), h = 2))

# Add a unique ID for each time group
    deerobs2$twomin_periodid<-as.factor(paste(deerobs2$Kamera_ID,deerobs2$time_group_minu,sep='-'))
# Select only the first eventid of each time group
    deerobs_twominsub<-deerobs2[!duplicated(deerobs2$twomin_periodid),]
# Select all the rows with these event IDs
    Deerobs_subset<-subset(deerobs2,deerobs2$eventid%in%deerobs_twominsub$eventid)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-13
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    相关资源
    最近更新 更多