group_by与mutate尺寸不匹配:按bird_ID分组生成Position.Burst.ID
解决方法
问题根源
你的错误是因为在mutate中调用pbid(data_table)时,传入的是整个数据集而非当前分组的子集,导致返回的Position.Burst.ID长度与分组后的行不匹配。此外,原函数直接修改输入的data.table并返回整个表,不符合mutate需要返回对应长度向量的要求。
修复自定义函数
修改pbid函数,使其仅接收时间戳向量并返回对应的burst ID向量,而非操作整个数据集:
pbid <- function(timestamps) { # 确保时间戳为POSIXct格式 timestamps <- as.POSIXct(timestamps, tz = "UTC") # 判断相邻时间差是否≥5秒,首行标记为新burst起点 is_new_burst <- c(TRUE, diff(timestamps) >= 5) # 获取所有新burst的起始行索引 burst_starts <- which(is_new_burst) # 生成每个行对应的burst ID burst_ids <- rep(seq_along(burst_starts), diff(c(burst_starts, length(timestamps) + 1))) return(burst_ids) }
使用dplyr分组计算
在group_by后,直接将分组内的timestamp列传入pbid函数即可:
library(dplyr) data_table %>% group_by(bird_ID) %>% mutate(Position.Burst.ID = pbid(timestamp)) %>% ungroup()
更高效的data.table原生写法
由于你使用的是data.table,推荐用原生分组语法,性能更优:
data_table[, Position.Burst.ID := pbid(timestamp), by = bird_ID]
验证示例
假设测试数据:
test_dt <- data.table( bird_ID = c("350E", "350E", "350E", "350F", "350F"), timestamp = as.POSIXct(c( "2022-05-02 00:03:59", "2022-05-02 00:04:01", "2022-05-02 00:04:06", "2022-05-02 00:05:00", "2022-05-02 00:05:02" ), tz = "UTC") )
运行data.table代码后,结果为:
bird_ID timestamp Position.Burst.ID 1: 350E 2022-05-02 00:03:59 1 2: 350E 2022-05-02 00:04:01 1 3: 350E 2022-05-02 00:04:06 2 4: 350F 2022-05-02 00:05:00 1 5: 350F 2022-05-02 00:05:02 1
符合预期:350E的第三行时间差≥5秒,分配新ID;350F的两行时间差<5秒,共用同一ID。
内容的提问来源于stack exchange,提问作者helianthus
相关产品推荐
相关产品推荐

