如何根据其他变量和时间间隔创建新变量(在 R 中)
Posted
技术标签:
【中文标题】如何根据其他变量和时间间隔创建新变量(在 R 中)【英文标题】:how to create a new variable according to others and to a time interval (in R) 【发布时间】:2021-03-10 17:13:06 【问题描述】:我需要根据一组变量的成员资格和 5 分钟的时间间隔为独立观察分配不同的值。 作为我的数据框的例子:
Fecha <- c(rep("22-05-2019", 9), rep("23-05-2019", 10), rep("24-05-2019", 3))
Noche <- c(rep(1,9), rep(2,13))
Parcela <- c(rep("CH1", 9), rep("CC1", 13))
Camara <- c(rep(2, 18), rep(3, 4))
Tratamiento <- c(rep("CHUNCHO", 9), rep("CONCON", 13))
Hora <- c("20:07", "20:10", "20:15", "23:19", "23:20", "23:22", "23:25", "23:43", "23:44", "22:10", "22:12", "22:13", "22:18", "22:39", "23:12", "23:29", "23:33", "23:43", "23:59", "0:21", "0:22", "1:20")
Especie <- c(rep("OL", 3), rep("AX", 4), rep("RR", 2), rep("AX", 5), rep("RR", 8))
datos <- data.frame(Fecha, Noche, Parcela, Camara, Tratamiento, Hora, Especie)
datos
# Fecha Noche Parcela Camara Tratamiento Hora Especie
1 22-05-2019 1 CH1 2 CHUNCHO 20:07 OL
2 22-05-2019 1 CH1 2 CHUNCHO 20:10 OL
3 22-05-2019 1 CH1 2 CHUNCHO 20:15 OL
4 22-05-2019 1 CH1 2 CHUNCHO 23:19 AX
5 22-05-2019 1 CH1 2 CHUNCHO 23:20 AX
6 22-05-2019 1 CH1 2 CHUNCHO 23:22 AX
7 22-05-2019 1 CH1 2 CHUNCHO 23:25 AX
8 22-05-2019 1 CH1 2 CHUNCHO 23:43 RR
9 22-05-2019 1 CH1 2 CHUNCHO 23:44 RR
10 23-05-2019 2 CC1 2 CONCON 22:10 AX
11 23-05-2019 2 CC1 2 CONCON 22:12 AX
12 23-05-2019 2 CC1 2 CONCON 22:13 AX
13 23-05-2019 2 CC1 2 CONCON 22:18 AX
14 23-05-2019 2 CC1 2 CONCON 22:39 AX
15 23-05-2019 2 CC1 2 CONCON 23:12 RR
16 23-05-2019 2 CC1 2 CONCON 23:29 RR
17 23-05-2019 2 CC1 2 CONCON 23:33 RR
18 23-05-2019 2 CC1 2 CONCON 23:43 RR
19 23-05-2019 2 CC1 3 CONCON 23:59 RR
20 24-05-2019 2 CC1 3 CONCON 0:21 RR
21 24-05-2019 2 CC1 3 CONCON 0:22 RR
22 24-05-2019 2 CC1 3 CONCON 1:20 RR
这将是分配的事件:
# Fecha Noche Parcela Camara Tratamiento Hora Especie Group Event
1 22-05-2019 1 CH1 2 CHUNCHO 20:07 OL AA 1
2 22-05-2019 1 CH1 2 CHUNCHO 20:10 OL AA 1
3 22-05-2019 1 CH1 2 CHUNCHO 20:15 OL AA 2
4 22-05-2019 1 CH1 2 CHUNCHO 23:19 AX AB 3
5 22-05-2019 1 CH1 2 CHUNCHO 23:20 AX AB 3
6 22-05-2019 1 CH1 2 CHUNCHO 23:22 AX AB 3
7 22-05-2019 1 CH1 2 CHUNCHO 23:25 AX AB 4
8 22-05-2019 1 CH1 2 CHUNCHO 23:43 RR AC 5
9 22-05-2019 1 CH1 2 CHUNCHO 23:44 RR AC 5
10 23-05-2019 2 CC1 2 CONCON 22:10 AX AD 6
11 23-05-2019 2 CC1 2 CONCON 22:12 AX AD 6
12 23-05-2019 2 CC1 2 CONCON 22:13 AX AD 6
13 23-05-2019 2 CC1 2 CONCON 22:18 AX AD 7
14 23-05-2019 2 CC1 2 CONCON 22:39 AX AD 8
15 23-05-2019 2 CC1 2 CONCON 23:12 RR AE 9
16 23-05-2019 2 CC1 2 CONCON 23:29 RR AE 10
17 23-05-2019 2 CC1 2 CONCON 23:33 RR AE 10
18 23-05-2019 2 CC1 2 CONCON 23:43 RR AE 11
19 23-05-2019 2 CC1 3 CONCON 23:59 RR AF 12
20 24-05-2019 2 CC1 3 CONCON 0:21 RR AF 13
21 24-05-2019 2 CC1 3 CONCON 0:22 RR AF 13
22 24-05-2019 2 CC1 3 CONCON 1:20 RR AF 14
“事件”将是一个新变量,其值或标签(可以是数字、字母、符号等)在组之间(由 Noche、Parcela、Camara、Tratamiento 和 Especie 提供)和组内不同(如果有)他们之间的时间超过5分钟。间隔开始将设置为一些早期观察,因此对于所有后续观察,它不会是 5 分钟的差异。 “组”列不是必需的,我只是为了阐明组,如果解决方案只为每个组提供独特的事件,这将很有用。
Ronak Shah 提供的解决方案非常接近:
library(dplyr)
datos %>%
tidyr::unite(datetime, Fecha, Hora, sep = ' ') %>%
mutate(datetime = dmy_hm(datetime)) %>%
group_by(Parcela, Camara, Tratamiento, Especie) %>%
mutate(grp = cut(datetime, breaks = '5 mins')) %>%
group_by(grp, .add = TRUE) %>%
mutate(Event = cur_group_id())
,但仍然存在一些错误。在示例中,第 16 行和第 17 行应该在同一个事件中,但使用此方法时会分开显示
【问题讨论】:
【参考方案1】:对于Plot
、Treatment
、Camera
和Species
的每个值,您可以使用cut
每5 分钟划分一次数据。使用cur_group_id
,我们在每个组中生成一个唯一的ID。
library(dplyr)
datos %>%
tidyr::unite(datetime, Fecha, Hora, sep = ' ') %>%
mutate(datetime = dmy_hm(datetime)) %>%
group_by(Parcela, Camara, Tratamiento, Especie) %>%
mutate(grp = cut(datetime, breaks = '5 mins')) %>%
group_by(grp, .add = TRUE) %>%
mutate(Event = cur_group_id()) -> result
result
【讨论】:
谢谢,但是当我运行它时显示:错误:mutate()
输入问题grp
。 x 'to' 必须是有限数 i 输入 grp
是 cut(Date_Time, breaks = "5 mins")
。 i 错误发生在第 1 组中:plot = "A", Treatment = "FOX", Camera = 1, Species = "AX"。
@RodrigoSalgadoMoya 请以可重现的格式添加您的数据样本,以供我们调试。阅读how to give a reproducible example。
在下面我的回答的“datos”上,我做了这个:datos$fechahora <- as.POSIXct(paste(datos$Fecha, datos$Hora), format = "%d-%m-%Y %H:%M") datos$group_id <- datos %>% group_by(Noche, Parcela, Camara, Tratamiento, Especie) %>% group_indices() datos <- datos %>% group_by(group_id) %>% mutate(grp = cut(fechahora, breaks = '5 mins')) %>% group_by(grp, .add = TRUE) %>% mutate(Event = cur_group_id())
但是在 #17 中的事件分配仍然有错误
@RodrigoSalgadoMoya 看看更新的答案是否有帮助。
谢谢。真的很近。我以为是它,但我发现了一些错误,我不知道为什么,我没有看到模式。 .例如:组内,时间(事件):1:49:00(17)、2:21:00(18)、2:23:00(19)、2:25:00(19)、2: 26:00 (19)【参考方案2】:
如果您的数据可以按 Plot、Treatment、Camera 和 Species 列排列/排序,那么您可以节省迭代部分来估计组标志并改用 dplyr::group_indices 函数。
这是我的解决方案:
# Load libraries
library(dplyr)
# Load data
plot <- c(rep("A", 4), rep("B", 4))
Treatment <- c(rep("FOX", 5), rep("EAGLE", 3))
Camera <- c(rep(1,5), rep(2,2), 1)
Species <- c(rep("AX", 3), "RR", rep("AX", 4))
date1 <- rep("2020-05-01", 8)
date2 <- c("20:20", "20:22", "20:26", "20:23", "20:20", "20:21", "20:23", "20:23")
Date_Time <- as.POSIXct(paste(date1, date2))
df <- data.frame(plot, Treatment, Camera, Species, Date_Time)
# Get count vector for each group and a 5 minutes change flag
df <- df %>%
group_by(plot, Treatment, Camera, Species) %>%
mutate(count = 1:n(),
time_change = ifelse(as.numeric(Date_Time - first(Date_Time)) / 60 < 5, 0, 1))
# Adjust the group flag to have a continuos one
count <- df$count
groups <- c(0, nrow(df))
for (k in 1:length(count))
delta <- count[k] - count[k-1]
if (k == 1)
groups[k] <- 1
else if (delta > 0)
groups[k] <- groups[k-1]
else
groups[k] <- groups[k-1] + 1
# Get final event flag
df$Event <- groups + cumsum(df$time_change)
df <- subset(df, select = -c(count, time_change))
【讨论】:
谢谢。我可以根据您的建议运行它,但只能在我作为示例制作的数据中运行,而不是在我的真实数据中。我不知道为什么。可能是因为日期和时间分开的时间数据格式,起初是字符,尽管我像你一样使用了“as.POSIXct(paste(date, time))”。我看到一个问题是在一个事件结束并开始另一个事件时建立一个标志或一个剪辑,因为不仅是每个组的第一个单元格给出的 如果我至少无法获得您的真实数据样本,我无法帮助您。发布的解决方案适用于您提供的示例。以上是关于如何根据其他变量和时间间隔创建新变量(在 R 中)的主要内容,如果未能解决你的问题,请参考以下文章