R中如何用tibble或替代方法计算每15行均值并存CSV?
分钟级数据按15行分组求均值的R实现问题解答
问题背景
有一个含4000多行、19列的分钟级数据文本文件,开头有若干行元数据,结构示例:
Few lines of metadata
Date Time AirTemp Pres Wind ....
2021-03-01 00:00:00 27 1017 10....
2021-03-01 00:01:00.....
原用以下R代码按每15行分组求均值:
df <- read.table('C:/Users/Alexia/Desktop/Test/Test1.txt', header=TRUE, sep = "\t", check.names = FALSE, skip=27) library(dplyr) df %>% group_by(group = as.integer(gl(n(), 15, n()))) %>% summarise_all(funs(mean))
运行后出现两个警告:
funs()在dplyr 0.8.0已弃用,需改用新语法;- 对
Date/Time列求均值报错(非数值类型),返回NA。
解答
1. funs()的未来可用性
funs()已被dplyr官方标记为弃用(deprecated),从dplyr 0.8.0版本开始就不再推荐使用,未来的dplyr版本大概率会彻底移除该函数,必须切换到官方推荐的新语法。
2. 是否推荐用tibble计算均值
tibble是dplyr生态中的一种数据框格式,dplyr的分组聚合操作默认返回tibble,但计算均值的核心逻辑还是依赖dplyr的summarise系列函数,不需要特意用tibble单独计算均值。只需用dplyr的新语法替代funs()即可,结果自然会以tibble格式输出,方便后续处理。
3. 正确实现方法(含CSV保存)
核心修正点:
- 替换
funs()为across()语法(dplyr 1.0.0+推荐); - 跳过非数值列(如
Date/Time)的均值计算,或为时间列保留每组的代表值(比如每组第一个时间); - 最后用
write.csv()或write_csv()(readr包)保存结果。
完整代码示例:
# 加载所需包 library(dplyr) # 读取数据(注意skip参数对应你的元数据行数) df <- read.table('C:/Users/Alexia/Desktop/Test/Test1.txt', header = TRUE, sep = "\t", check.names = FALSE, skip = 27, stringsAsFactors = FALSE) # 将Date/Time转为时间类型(如果原数据是Date+Time两列,可先合并再转换) df$`Date/Time` <- as.POSIXct(df$`Date/Time`, format = "%Y-%m-%dT%H:%M:%S") # 按每15行分组,计算数值列均值,保留每组第一个时间 result <- df %>% group_by(group = as.integer(gl(n(), 15, n()))) %>% summarise( # 保留每组的起始时间 `Date/Time` = first(`Date/Time`), # 对所有数值列计算均值 across(where(is.numeric), mean, na.rm = TRUE) ) %>% # 移除辅助分组列(可选,根据需求保留) select(-group) # 保存为CSV文件 write.csv(result, 'C:/Users/Alexia/Desktop/Test/15min_mean_data.csv', row.names = FALSE, fileEncoding = "UTF-8")
针对样本数据的测试代码:
用你提供的样本dput数据测试:
# 加载样本数据 sample_df <- structure(list(`Date/Time` = c("2021-03-01T00:00:00", "2021-03-01T00:01:00", "2021-03-01T00:02:00", "2021-03-01T00:03:00"), `XY` = c(990641, 41, 641, 906), `R1` = c(250, 27, 57, 56), `R2` = c(85, 84, 89, 64)), class = "data.frame", row.names = c(NA, -4)) # 转换时间类型 sample_df$`Date/Time` <- as.POSIXct(sample_df$`Date/Time`, format = "%Y-%m-%dT%H:%M:%S") # 按每2行分组测试(因为样本只有4行) sample_result <- sample_df %>% group_by(group = as.integer(gl(n(), 2, n()))) %>% summarise( `Date/Time` = first(`Date/Time`), across(where(is.numeric), mean, na.rm = TRUE) ) %>% select(-group) print(sample_result)
输出结果:
# A tibble: 2 × 4 `Date/Time` XY R1 R2 <dttm> <dbl> <dbl> <dbl> 1 2021-03-01 00:00:00 495341 138.5 84.5 2 2021-03-01 00:02:00 773.5 56.5 76.5
内容的提问来源于stack exchange,提问作者Alexia k Boston
相关产品推荐
相关产品推荐

