问题描述
这是我正在使用的 df 中的一个小样本:
animal time period zone
<chr> <dbl> <chr> <chr>
1 HR1 0 q1 social
2 HR1 2.04 q1 social
3 HR1 2.1 q1 social
4 HR1 2.20 q1 interzone
5 HR1 2.44 q1 nest
6 HR1 2.47 q1 nest
7 HR1 2.68 q1 nest
8 HR1 2.71 q1 nest
9 HR1 2.87 q1 nest
10 HR1 3.20 q1 nest
我试图找到一种方法来计算动物在每个区域花费的时间。我实际上希望生成另一列,在该列中我可以获得每次访问该区域的累积时间。这将包括在区域中获取最大和最小时间点,减去它们,并将最终结果放入新列中。最终结果应如下所示:
animal time period zone cum_time_zone
<chr> <dbl> <chr> <chr> <dbl>
1 HR1 0 q1 social NA
2 HR1 2.04 q1 social NA
3 HR1 2.1 q1 social 2.2
4 HR1 2.20 q1 interzone 0.24
5 HR1 2.44 q1 nest NA
6 HR1 2.47 q1 nest NA
7 HR1 2.68 q1 nest NA
8 HR1 2.71 q1 nest NA
9 HR1 2.87 q1 nest NA
10 HR1 3.20 q1 nest 0.76
我将非常感谢您的任何意见!
解决方法
使用data.table
:
library(data.table)
setDT(data)
data[,cum_time_zone := c(0,diff(time))][,cum_time_zone:=fifelse(time==max(time),sum(cum_time_zone),NA_real_),by=rleid(animal,zone)]
data
animal time period zone cum_time_zone
1: HR1 0.00 q1 social NA
2: HR1 2.04 q1 social NA
3: HR1 2.10 q1 social 2.1
4: HR1 2.20 q1 interzone 0.1
5: HR1 2.44 q1 nest NA
6: HR1 2.47 q1 nest NA
7: HR1 2.68 q1 nest NA
8: HR1 2.71 q1 nest NA
9: HR1 2.87 q1 nest NA
10: HR1 3.20 q1 nest 1.0
数据:
data <- read.table(text="
animal time period zone
1 HR1 0 q1 social
2 HR1 2.04 q1 social
3 HR1 2.1 q1 social
4 HR1 2.20 q1 interzone
5 HR1 2.44 q1 nest
6 HR1 2.47 q1 nest
7 HR1 2.68 q1 nest
8 HR1 2.71 q1 nest
9 HR1 2.87 q1 nest
10 HR1 3.20 q1 nest ",header=T)
,
这是一种 dplyr
方法 -
library(dplyr)
df %>%
group_by(animal) %>%
mutate(cum_time_zone = time - lag(time,default = 0)) %>%
group_by(zone,.add = TRUE) %>%
mutate(cum_time_zone = case_when(n() == 1 ~ cum_time_zone,row_number() == n()~ max(time) - min(time))) %>%
ungroup()
# animal time period zone cum_time_zone
# <chr> <dbl> <chr> <chr> <dbl>
# 1 HR1 0 q1 social NA
# 2 HR1 2.04 q1 social NA
# 3 HR1 2.1 q1 social 2.1
# 4 HR1 2.2 q1 interzone 0.100
# 5 HR1 2.44 q1 nest NA
# 6 HR1 2.47 q1 nest NA
# 7 HR1 2.68 q1 nest NA
# 8 HR1 2.71 q1 nest NA
# 9 HR1 2.87 q1 nest NA
#10 HR1 3.2 q1 nest 0.76
数据
df <- structure(list(animal = c("HR1","HR1","HR1"),time = c(0,2.04,2.1,2.2,2.44,2.47,2.68,2.71,2.87,3.2),period = c("q1","q1","q1"),zone = c("social","social","interzone","nest","nest")),class = "data.frame",row.names = c(NA,-10L))