如何结合rowwise与case_when处理缺失值并计算行最大值
问题原因
case_when的所有分支表达式会提前全部计算,而非仅执行满足条件的分支。即使第6行count_not_na > 0为FALSE,max(c(col_a, col_b), na.rm = TRUE)依然会被执行——当输入全为NA时,max(..., na.rm = TRUE)会返回-Inf并触发警告,之后case_when才会选择T ~ NA_real_的分支赋值,因此最终结果正确,但警告无法消除。
优雅解法
解法1:用pmax处理少量列(推荐)
pmax原生支持按行计算多列最大值,且当所有输入为NA且na.rm = TRUE时,会直接返回NA,无警告:
library(tidyverse) data <- tibble(col_a = rep(c(2, 1, NA_real_), each = 2), col_b = rep(c(2, 1, NA_real_), times = 2)) %>% mutate(max_value = pmax(col_a, col_b, na.rm = TRUE))
输出结果:
| col_a | col_b | max_value |
|---|---|---|
| 2 | 2 | 2 |
| 2 | 1 | 2 |
| 1 | NA | 1 |
| 1 | 2 | 2 |
| NA | 1 | 1 |
| NA | NA | NA |
解法2:用c_across处理任意多列
如果数据集有大量列,用c_across指定列范围,结合if_else判断是否存在非NA值,避免无效计算:
data <- tibble(col_a = rep(c(2, 1, NA_real_), each = 2), col_b = rep(c(2, 1, NA_real_), times = 2)) %>% rowwise() %>% mutate(max_value = if_else( any(!is.na(c_across(col_a:col_b))), # 判断是否有非NA值 max(c_across(col_a:col_b), na.rm = TRUE), NA_real_ )) %>% ungroup() # 取消行分组,恢复高效计算
解法3:替换max返回的-Inf为NA
如果坚持用原思路,可将max返回的-Inf替换为NA,避免警告:
data <- tibble(col_a = rep(c(2, 1, NA_real_), each = 2), col_b = rep(c(2, 1, NA_real_), times = 2)) %>% rowwise() %>% mutate(max_value = replace( max(c(col_a, col_b), na.rm = TRUE), all(is.na(c(col_a, col_b))), NA_real_ )) %>% ungroup()
内容的提问来源于stack exchange,提问作者C. Sebastian
相关产品推荐
相关产品推荐

