如何在R中按日期对多变量计算每日均值并保留标识字段?
在R中计算多变量的每日均值(保留分组信息)
我来帮你搞定这个需求——按id、city和日期分组,计算temperature、pressure这类变量的每日均值,同时保留关键的分组信息。下面给你两种实用的解决方案,分别适配不同的数据规模:
方法一:用dplyr(语法直观,适合中小数据量)
dplyr的链式语法很容易理解,配合lubridate处理时间会更顺手,适合日常分析场景:
# 先加载需要的包 library(dplyr) library(lubridate) # 你的示例数据 data <- data.frame( "id" = c(1,1, 3,3,5,5), "city" = c("new_york", "new_york", "london", "london", "barcelona", "barcelona"), "temperature" = c(15, 16, 13, 12, 30, 32), "pressure" = c(1000, 1003, 980, 998, 1013, 1015), "time" = c("2015-01-01 06:30:00","2015-01-01 18:30:00", "2015-02-10 07:00:00", "2015-02-10 20:30:00", "2015-04-08 08:00:00", "2015-04-08 12:00:00"), stringsAsFactors = FALSE ) # 计算每日均值的核心代码 daily_avg <- data %>% # 把字符型的time转成日期时间格式,再提取纯日期 mutate(date = as_date(time)) %>% # 按id、city、日期分组 group_by(id, city, date) %>% # 自动对所有数值列计算均值(不用手动列每一列,适合你有更多变量的情况) summarise(across(where(is.numeric), mean), .groups = "drop") %>% # 把date列重命名为time,匹配你要的输出格式 rename(time = date) # 查看结果 print(daily_avg)
代码细节说明:
across(where(is.numeric), mean)会自动识别所有数值列并计算均值,不管你后续加多少列(比如precipitation)都不用改这行.groups = "drop"是为了分组后取消分组状态,避免后续操作出现不必要的警告- 如果只想计算特定列(比如只算temperature和pressure),可以把
across(where(is.numeric), mean)改成across(c(temperature, pressure), mean)
方法二:用data.table(效率拉满,适合大数据量)
如果你的实际数据有几十万甚至上百万行,data.table的速度会比dplyr快很多,非常适合处理大规模数据集:
# 加载data.table包 library(data.table) # 把普通data.frame转成data.table格式 setDT(data) # 计算每日均值 daily_avg_dt <- data[, # 对指定列计算均值,同时提取日期 c(lapply(.SD, mean), .(date = as.Date(time))), # 分组依据:id、city和日期 by = .(id, city, date = as.Date(time)), # 指定要计算均值的列:所有数值列 .SDcols = sapply(data, is.numeric)] %>% # 调整列顺序,和你期望的输出一致 setcolorder(c("id", "city", "temperature", "pressure", "date")) %>% # 重命名date为time setnames("date", "time") # 查看结果 print(daily_avg_dt)
代码细节说明:
.SDcols = sapply(data, is.numeric)指定只对数值列计算均值,同样支持自动识别新增的变量by参数直接指定分组键,语法简洁高效- 如果要处理缺失值,可以在
mean里加上na.rm = TRUE,比如lapply(.SD, function(x) mean(x, na.rm = TRUE))
最终输出结果
两种方法都会得到和你期望完全一致的输出:
id city temperature pressure time 1 1 new_york 15.5 1001.5 2015-01-01 2 3 london 12.5 989.0 2015-02-10 3 5 barcelona 31.0 1014.0 2015-04-08
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

