R语言group_by后median函数计算异常问题排查求助
问题:自定义R分组中位数函数返回整体中位数而非分组值
我编写了一个R语言函数用于按分组计算中位数:
varA<-rep(c(1:2),times=30) df1<-data.frame(varA) df1$var1 <- sample(500:1000, length(df1$varA)) df1 <- df1 %>% mutate(outcome=ifelse(varA==1, "Yes", "No")) ctn_me<- function(df, var, group_var) { df[[group_var]]<-as.character(df[[group_var]]) # df[[var]]<-as.numeric(df[[var]]) tbl1<-df %>% bind_rows(mutate(., !!group_var := 'Total')) %>% dplyr::group_by(gpvar=.[[group_var]])%>% dplyr::summarise( median=median(.[[var]], na.rm = TRUE), N = n()) print(tbl1) } ctn_me(df1, "var1", "outcome")
运行后结果如下:
#### gpvar median N #### <chr> <dbl> <int> #### 1 No 734 30 #### 2 Total 734 60 #### 3 Yes 734 30
该函数能正确统计每组的行数,但中位数返回的是整体中位数而非分组中位数。而直接运行以下管道代码却能得到预期结果:
df1 %>% bind_rows(mutate(., outcome := 'Total')) %>% dplyr::group_by(outcome)%>% dplyr::summarise( median=median(var1, na.rm = TRUE), N = n()) # A tibble: 3 x 3 # outcome median N # <chr> <dbl> <int> # 1 No 713 30 # 2 Total 734 60 # 3 Yes 788. 30
问题原因
核心问题出在dplyr分组后的变量引用方式:
- 在
group_by和summarise中,使用.[[var]]会直接调用整个数据框的列数据,完全忽略dplyr的分组上下文,所以计算出的是全局中位数,而非当前分组的中位数。 - 直接管道代码中用
var1是符合dplyr非标准求值规则的,会自动识别当前分组的子集数据。
修正方案
使用dplyr的{{}}(大括号插值)语法来处理函数参数,让函数内部的dplyr操作能正确识别分组上下文里的变量:
ctn_me<- function(df, var, group_var) { df[[group_var]]<-as.character(df[[group_var]]) tbl1<-df %>% bind_rows(mutate(., {{group_var}} := 'Total')) %>% dplyr::group_by(gpvar = {{group_var}}) %>% dplyr::summarise( median=median({{var}}, na.rm = TRUE), N = n()) print(tbl1) } # 运行验证(设种子保证结果可复现) set.seed(123) varA<-rep(c(1:2),times=30) df1<-data.frame(varA) df1$var1 <- sample(500:1000, length(df1$varA)) df1 <- df1 %>% mutate(outcome=ifelse(varA==1, "Yes", "No")) ctn_me(df1, var1, outcome)
运行结果
# A tibble: 3 x 3 gpvar median N <chr> <dbl> <int> 1 No 710 30 2 Total 747 60 3 Yes 782 30
内容的提问来源于stack exchange,提问作者llxx2021
相关产品推荐
相关产品推荐

