tidyverse summarise函数行为是否变更?Shiny应用统计代码报错
问题描述
我有一个已运行许久的Shiny应用,其中功能之一是为数据框生成统计表格,此前以下代码一直可正常运行:
library(shiny) #library(dashboardthemes) library(readxl) library(readODS) library(tidyverse) # data wrangling library(viridis) # for colour-blind friendly palettes library(ggplot2) # pretty plots library(scales) library(PerformanceAnalytics)# for statistics library(EnvStats) library(ggbeeswarm) ... code ... Stats <- graphData() %>% group_by(Analyte) %>% summarise( .groups="keep", Count = sum(!is.na(Concentration)), # Number of samples Minimum = min(Concentration), # Minimum Average = mean(Concentration), # Mean Median = median(Concentration), # Median Maximum = max(Concentration), # Maximum Range = Maximum - Minimum # Range )
graphData()函数返回包含Analyte名称与Concentration值的数据框。近期修改脚本其他部分后,该summarise函数突然失效,报错提示:Error: object 'Maximum' not found。此前我可以在summarise语句中引用刚定义的变量(比如用Maximum计算Range),想知道是summarise函数的行为发生了变更,还是存在其他问题?我的RStudio版本为2023.09.0+463 "Desert Sunflower"(Ubuntu Jammy系统)。我可以通过后续的mutate重写代码,但更希望能保留原有写法。
解决方案与原因
这是dplyr版本更新导致的行为变化:在dplyr 1.1.0及以后的版本中,summarise默认不再支持在同一次调用内引用刚生成的新列。旧版本允许这种“即时引用”,但新版本为了消除求值顺序的歧义,改为所有列的计算都基于原始分组数据框,而非本次summarise中生成的列。
要保留原有写法,有两种直接方案:
- 方案1:使用
rowwise()
在group_by之后添加rowwise(),让summarise按行处理,支持即时引用新生成的列:Stats <- graphData() %>% group_by(Analyte) %>% rowwise() %>% summarise( .groups="keep", Count = sum(!is.na(Concentration)), Minimum = min(Concentration), Average = mean(Concentration), Median = median(Concentration), Maximum = max(Concentration), Range = Maximum - Minimum ) %>% ungroup() # 按需取消行分组,避免后续操作受影响 - 方案2:拆分
summarise与mutate
先计算所有不依赖的统计量,再用mutate计算依赖列,这也是新版本推荐的写法:Stats <- graphData() %>% group_by(Analyte) %>% summarise( .groups="keep", Count = sum(!is.na(Concentration)), Minimum = min(Concentration), Average = mean(Concentration), Median = median(Concentration), Maximum = max(Concentration) ) %>% mutate(Range = Maximum - Minimum)
如果非要沿用旧逻辑,也可以临时回退到dplyr 1.0.x版本,但不推荐长期这么做,建议适配新的求值逻辑以保证代码兼容性。
内容的提问来源于stack exchange,提问作者tim
相关产品推荐
相关产品推荐

