如何基于DayNight连续分组计算Sv_Ln的均值(R语言)
按连续DayNight分组计算Sv_Ln均值的R实现
问题说明
需要基于DayNight列的连续相同分组计算Sv_Ln的均值,而非将所有Day或Night合并计算。例如示例数据中,前2行连续Night为一组、接下来2行连续Day为一组、再2行连续Night为一组,每个独立连续分组单独求均值,且分组行数不固定(最多12行)。
示例数据集
# 示例数据 exports_15E <- data.frame( Date_M = c(20211213, 20211213, 20211213, 20211213, 20211213, 20211213, 20211214, 20211214, 20211214, 20211214), Time_M = c("18:22:22", "19:22:23", "06:22:23", "07:22:23", "22:22:22", "23:22:22", "06:22:23", "07:22:22", "02:22:22", "03:22:22"), Date_time = as.POSIXct(c("2021-12-13 18:22:00", "2021-12-13 19:22:00", "2021-12-13 06:22:00", "2021-12-13 07:22:00", "2021-12-13 22:22:00", "2021-12-13 23:22:00", "2021-12-14 06:22:00", "2021-12-14 07:22:00", "2021-12-14 02:22:00", "2021-12-14 03:22:00"), tz = "Asia/Bangkok"), DayNight = c("Night", "Night", "Day", "Day", "Night", "Night", "Day", "Day", "Night", "Night"), Sv_Ln = c(0.00000195, 0.00000266, 0.00000313, 0.00000526, 0.00000409, 0.00000658, 0.00000579, 0.00000724, 0.00000733, 0.00000745) )
解决方案
方法1:使用data.table包(简洁高效)
利用data.table的rleid()函数生成连续分组标识,该函数会为连续相同的DayNight值分配唯一组ID:
library(data.table) # 转换为data.table格式 setDT(exports_15E) # 按连续DayNight分组计算均值,同时保留分组的DayNight类型和时间范围 daily_avg_15E <- exports_15E[, .( Sv_Ln_mean = mean(Sv_Ln), start_time = min(Date_time), end_time = max(Date_time) ), by = .(group_id = rleid(DayNight), DayNight)] # 可选:将均值转换回对数格式 daily_avg_15E[, Sv_log := 10 * log10(Sv_Ln_mean)] # 查看结果 daily_avg_15E
方法2:使用base R实现
通过cumsum()和diff()生成连续分组标识,无需额外包:
# 生成连续分组ID exports_15E$group_id <- c(1, cumsum(diff(as.integer(factor(exports_15E$DayNight))) != 0) + 1) # 按分组ID和DayNight计算均值 daily_avg_15E <- aggregate( Sv_Ln ~ group_id + DayNight, data = exports_15E, FUN = mean ) # 添加时间范围(可选) time_ranges <- aggregate( Date_time ~ group_id, data = exports_15E, FUN = function(x) c(start = min(x), end = max(x)) ) daily_avg_15E <- merge(daily_avg_15E, do.call(data.frame, time_ranges), by = "group_id") # 转换回对数格式 daily_avg_15E$Sv_log <- 10 * log10(daily_avg_15E$Sv_Ln) # 重命名均值列 colnames(daily_avg_15E)[colnames(daily_avg_15E) == "Sv_Ln"] <- "Sv_Ln_mean" # 查看结果 daily_avg_15E
结果说明
两种方法都会得到每个连续DayNight分组的均值,示例数据的输出会包含5个分组(对应示例中的5组连续相同DayNight),每个分组的Sv_Ln_mean为该组的均值,同时可保留分组的时间范围和对数转换后的值。
内容的提问来源于stack exchange,提问作者Jackson A Swan
相关产品推荐
相关产品推荐

