如何在dplyr中计算行和与行最大值,互不包含且保留所有列
问题描述
我需要给数据框同时计算行和与行最大值,要求:
- 行和列不能参与最大值的计算
- 最大值列不能参与行和的计算
- 最终要保留包含这两个新列的完整数据集
我用dplyr写了这段代码:
iris <- iris %>% mutate(readsum = rowSums(across(where(is.numeric)), na.rm=TRUE)) iris_max <- iris %>% rowwise()%>% select(-"readsum")%>% mutate(readmax = max(across(where(is.numeric)), na.rm=TRUE))
但这段代码只会在新生成的iris_max里移除readsum列,没法得到同时包含readsum和readmax的完整数据集。
我想要的输出是这样的:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species readsum readmax <dbl> <dbl> <dbl> <dbl> <fct> <dbl> <dbl> 1 5.1 3.5 1.4 0.2 setosa 10.2 5.1 2 4.9 3 1.4 0.2 setosa 9.5 4.9 3 4.7 3.2 1.3 0.2 setosa 9.4 4.7 4 4.6 3.1 1.5 0.2 setosa 9.4 4.6 5 5 3.6 1.4 0.2 setosa 10.2 5 6 5.4 3.9 1.7 0.4 setosa 11.4 5.4
解决方案
你之前的问题在于拆分了两个独立管道,第二个管道里用select(-"readsum")直接删掉了行和列,最后得到的iris_max自然没有readsum。可以在同一个dplyr管道里完成所有操作,下面是几种可行的方法:
方法1:指定原始数值列(最直观)
直接明确要计算的原始数值列范围,这样行和与最大值都只基于原始列,不会互相干扰:
iris <- iris %>% # 基于原始4个数值列计算行和 mutate(readsum = rowSums(across(Sepal.Length:Petal.Width), na.rm = TRUE)) %>% # 同样基于原始4个数值列计算行最大值 rowwise() %>% mutate(readmax = max(across(Sepal.Length:Petal.Width), na.rm = TRUE)) %>% ungroup()
方法2:动态排除新生成的列
如果不想硬编码列名,可以用where(is.numeric)配合排除readsum列:
iris <- iris %>% mutate(readsum = rowSums(across(where(is.numeric)), na.rm = TRUE)) %>% rowwise() %>% # 排除readsum列后计算最大值 mutate(readmax = max(across(where(is.numeric) & !matches("readsum")), na.rm = TRUE)) %>% ungroup()
方法3:高效无rowwise写法(适合大数据)
rowwise()在处理大数据时效率较低,可以用pmap_dbl代替,提前定义目标列更清晰:
# 定义要计算的原始数值列 num_cols <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width") iris <- iris %>% mutate( readsum = rowSums(across(all_of(num_cols)), na.rm = TRUE), # 用pmap_dbl逐行计算最大值,无需rowwise readmax = pmap_dbl(across(all_of(num_cols)), ~max(c(...), na.rm = TRUE)) )
内容的提问来源于stack exchange,提问作者sscoresby
相关产品推荐
相关产品推荐

