R语言中计算数据框指定列行均值时排除0值的解决方案
问题:计算数据框指定列区间内的均值并排除0值
我需要计算数据框中指定两列区间内数据点的均值,目前用tidyverse写了如下代码:
library(tidyverse) Book7 <- read_excel("C:/X/X/X- X/X/Book7.xlsx",sheet = "Sheet12") Start_Date <- tail(head(colnames(Book7),3),1) End_Date <- tail(colnames(Book7),1) Book7 <- head(Book7,2) Book7 <- Book7 %>% mutate(Average = rowMeans(pick(any_of(Start_Date):any_of(End_Date)),na.rm = T))
当前代码能运行,但na.rm=T只排除NA值,计算均值时仍包含0值。用下面的测试数据集:
structure(list(Material = c("XAB-01-02-03", "XAB-01-02-03"), `Calendar Year/Week` = c("Deal", "Profit"), `2023/28` = c(6, 4), `2023/29` = c(92, 92), `2023/30` = c(81, 56), `2023/31` = c(5, 0), `2023/32` = c(54, 41), `2023/33` = c(82, 73), `2023/34` = c(30, 40), `2023/35` = c(46, 1), `2023/36` = c(4, 43), `2023/37` = c(83, 73), `2023/38` = c(78, 75), `2023/39` = c(85, 18), `2023/40` = c(60, 38), `2023/41` = c(51, 61), `2023/42` = c(65, 94), `2023/43` = c(74, 65), `2023/44` = c(12, 20), `2023/45` = c(1, 65)), row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame"))
第二行当前均值是47,排除0值后应该是50.52,希望修改代码实现排除0值计算均值的需求。
解决方案
可以通过自定义行均值逻辑,在计算时同时排除0和NA值,以下是两种符合tidyverse风格的实现方式:
方法1:使用apply结合过滤逻辑
Book7 <- Book7 %>% mutate(Average = apply(pick(any_of(Start_Date):any_of(End_Date)), 1, function(x) mean(x[x != 0], na.rm = TRUE)))
方法2:使用rowwise+c_across(更贴合tidyverse语法)
Book7 <- Book7 %>% rowwise() %>% mutate(Average = { # 提取当前行的目标列数据 target_cols <- c_across(any_of(Start_Date):any_of(End_Date)) # 过滤掉0值后计算均值,同时排除NA mean(target_cols[target_cols != 0], na.rm = TRUE) }) %>% ungroup()
效果说明
- 两种方法都会先筛选每行中不等于0的值,再计算均值,同时保留对NA值的排除逻辑
- 测试数据中第二行计算后结果为
50.52(保留两位小数),符合预期
内容的提问来源于stack exchange,提问作者user20203146
相关产品推荐
相关产品推荐

