我从动物发射机那里收集了很长的数据。由于发射器太阳能电池的充电量可变,因此数据点之间的间隔高度可变(范围从180秒到一小时以上)。我想对数据进行子集处理,以便点之间的间隔至少为10分钟或600秒。
这是我的一小部分数据的样子:
datetime id
01/09/2015 14:10:54 A
01/09/2015 14:26:56 A
01/09/2015 14:41:28 A
01/09/2015 14:43:53 A
01/09/2015 14:46:37 A
01/09/2015 14:48:57 A
01/09/2015 14:51:31 A
01/09/2015 14:54:08 A
04/09/2015 14:37:07 B
04/09/2015 14:52:07 B
04/09/2015 15:07:04 B
04/09/2015 15:15:35 B
04/09/2015 15:18:00 B
04/09/2015 15:20:23 B
04/09/2015 15:22:49 B
04/09/2015 15:25:12 B
04/09/2015 15:28:52 B
我希望的最小间隔为10分钟的输出为:
datetime id
01/09/2015 14:10:54 A
01/09/2015 14:26:56 A
01/09/2015 14:41:28 A
01/09/2015 14:51:31 A
01/09/2015 14:37:07 B
04/09/2015 14:52:07 B
04/09/2015 15:07:04 B
04/09/2015 15:18:00 B
04/09/2015 15:28:52 B
我发现了一个几乎准确的问题,答案为here。他们的数据包括ID,日期和时间。这是答案中给出的代码:
library(dplyr)
library(lubridate)
locdata %>%
mutate(timestamp = dmy_hm(paste(date, time))) %>%
group_by(id, date) %>%
mutate(delta = timestamp - first(timestamp),
steps = as.numeric(floor(delta / 3600)),
change = ifelse(is.na(steps - lag(steps)), 1, steps - lag(steps))) %>%
filter(change > 0) %>%
select(id, date, timestamp)
我对此略作调整,如下所示:
result <- mydata %>%
group_by(id) %>%
mutate(delta = datetime - first(datetime),
steps = as.numeric(floor(delta / 600)),
change = ifelse(is.na(steps - lag(steps)), 1, steps - lag(steps)))
代码将显示以下输出:
datetime id delta steps change
01/09/2015 14:10:54 A 0 0 1
01/09/2015 14:26:56 A 962 1 1
01/09/2015 14:41:28 A 1834 3 2
01/09/2015 14:51:31 A 2437 4 1
04/09/2015 14:37:07 B 0 0 1
04/09/2015 14:52:07 B 900 1 1
04/09/2015 15:07:04 B 1797 2 1
04/09/2015 15:15:35 B 2308 3 1
04/09/2015 15:18:00 B 2453 4 1
04/09/2015 15:22:29 B 3105 5 1
输出给出从10点(每个id)开始的每个10分钟时间段的第一个数据点。这并不是我真正需要的,因为某些时间点相距不到10分钟。我需要的是下一次在每个ID内距上一个点 10分钟或更长时间的下一次。
有人知道我该怎么做吗?我需要使用循环吗?谢谢你的想法。
答案 0 :(得分:0)
我有一个使用dplyr(带有lead()
函数)和while循环的想法,它可能对您有帮助
library(dplyr)
library(lubridate)
data <- data %>%
mutate(date = lubridate::ymd_hms(datetime),
id_rows = 1:nrow(.)) %>%
group_by(id) %>%
mutate(delta = lubridate::time_length(lag(date) %--% date, unit = "sec"))
while (min(data$delta, na.rm = T) < 600) {
rm_rows <- data %>%
filter(delta < 600) %>%
filter(date == min(date)) %>%
pull(id_rows)
data <- data %>%
filter(!id_rows %in% rm_rows) %>%
mutate(delta = lubridate::time_length(lag(date) %--% date, unit = "sec"))
}