如何在R中仅当指定比例数据非缺失时计算每10行均值
解决方案
你的需求核心是每10行分组计算列均值时,仅当该列在组内的非缺失值占比≥5%才计算均值,否则标记为NA。以下是修改后的完整代码,关键调整了判断条件,同时修正了原代码的语法问题:
library(dplyr) library(tidyr) library(lubridate) # 读取数据 df <- read.table('D:/Test/Data.txt', header=TRUE, sep = "\t", check.names = FALSE) # 拆分Date/Time列为Date和Time mn <- df %>% separate(`Date/Time`, into = c("Date", "Time"), sep = "T") # 分组计算均值并应用条件 mnf <- mn %>% as_tibble() %>% # 按每10行分组 group_by(group = as.integer(gl(n(), 10, n()))) %>% # 转换日期和时间格式 mutate( Date = lubridate::ymd(Date), Time = period_to_seconds(hms(Time)) ) %>% # 按列计算均值,添加非缺失值占比≥5%的条件 summarise( across(everything(), ~ if(mean(!is.na(.x)) < 0.05) { NA } else { mean(.x, na.rm = TRUE) }), .groups = "drop" # 取消分组,避免后续操作报错 ) %>% # 将Time转换回周期格式 mutate(Time = seconds_to_period(Time)) # 查看结果 mnf
关键修改说明
- 条件逻辑调整:
用mean(!is.na(.x)) < 0.05判断非缺失值占比是否低于5%——如果是,返回NA;否则计算均值。原代码的mean(is.na(.x)) > 0.8是针对缺失率超过80%的场景,和你的需求不匹配,这里替换为符合5%非缺失要求的判断。 - 语法修正:
在summarise中添加.groups = "drop"取消分组状态,避免后续mutate操作出现分组冲突;同时将mutate(Time = seconds_to_period(Time))通过管道连接到summarise之后,保证代码可正常运行。 - Date列优化(可选):
如果每组的Date是相同的,你可以把Date列的处理改为保留组内首个/末次日期而非均值,更符合业务逻辑:summarise( Date = first(Date), # 保留组内第一个日期,也可改用last(Date) across(-Date, ~ if(mean(!is.na(.x)) < 0.05) NA else mean(.x, na.rm = TRUE)), .groups = "drop" )
内容的提问来源于stack exchange,提问作者Michael_Brun
相关产品推荐
相关产品推荐

