使用if_else条件无法规避min函数的“no non-missing arguments to min; returning Inf”警告问题排查
为什么用if_else过滤分组后仍触发min()的警告?如何避免?
问题原因
你遇到的问题核心是if_else()的工作机制:它是向量化的条件函数,会先完整计算true和false两个分支的所有表达式,再根据条件选择对应结果。也就是说,哪怕你指定了group == 1才执行min(),处理group=2的分组时,那个min(x[x %in% ...], na.rm=TRUE)的代码依然会被执行一遍。而group2里没有符合筛选条件的元素,x[x %in% c(998,9991,9992)]会变成空向量,此时调用min(空向量, na.rm=TRUE)就会触发你看到的警告。
解决方案
下面给你几种可行的修改方式,都能避免警告且得到预期结果:
方法1:用标量if替代向量化if_else
因为我们是按group分组的,每个分组内的group值是唯一的标量,所以可以用普通的if()(标量条件判断)来替代if_else()。这样只有当条件为真时,min()的代码才会被执行:
library(tidyverse) df %>% group_by(group) %>% mutate(test = if (group == 1) min(x[x %in% c(998, 9991, 9992)], na.rm = TRUE) else NA_real_)
方法2:提前判断筛选后的向量是否为空
如果坚持要用向量化的if_else,可以在min的表达式里先检查筛选后的向量是否有元素,没有的话直接返回NA,避免调用空向量的min:
df %>% group_by(group) %>% mutate(test = if_else(group == 1, ifelse(length(x[x %in% c(998, 9991, 9992)]) > 0, min(x[x %in% c(998, 9991, 9992)], na.rm = TRUE), NA_real_), NA_real_))
方法3:先汇总再关联(更清晰的逻辑)
另一种更清晰的思路是先单独计算每个分组的目标值,再把结果关联回原数据框。这种方法把分组计算和数据合并分开,可读性和维护性更好:
# 第一步:计算每个group的目标最小值 summary_df <- df %>% group_by(group) %>% summarize(test = if (any(x %in% c(998, 9991, 9992))) { min(x[x %in% c(998, 9991, 9992)], na.rm = TRUE) } else { NA_real_ }) # 第二步:关联回原数据 df %>% left_join(summary_df, by = "group")
以上三种方法都能得到你预期的输出结果,且不会触发任何警告。
内容的提问来源于stack exchange,提问作者deschen
相关产品推荐
相关产品推荐

