首页 > 解决方案 > 为什么在 R 中将 `format()` 与 `dplyr` 一起使用会出现奇怪的行为?

问题描述

我正在尝试使用dplyr %>%管道将数值舍入并格式化为小数点后有 2 位数字(例如 2.43、1.05)。但是,该format()函数在以下两个数据示例(df_summarizedf_groupby)中具有不同的行为。的输出df_summarize是正确的,但输出df_groupby不正确,我想知道有线行为的原因是什么。是因为分组效应还是其他原因?

任何建议表示赞赏。

library(tidyverse)

df <- data.frame(cate = sample(c("A", "B"), size = 5, replace = T),
                 v1 = runif(5, 1.001, 5.005), 
                 v2 = runif(5, 1.001, 5.005))

df_summarize <- df %>% summarise(mean_v1 = mean(v1),
                                 mean_v2 = mean(v2)) %>% 
  round(2) %>% format(nsmall = 2)

#   mean_v1 mean_v2
# 1    3.94    2.08

df_groupby <- df %>% group_by(cate) %>% 
  summarise(p1 = mean(v1), p2 = mean(v2)) %>% 
  select(-cate) %>% ungroup() %>% 
  round(2) %>% format(nsmall = 2)

# [1] "\033[38;5;246m# A tibble: 2 × 2\033[39m"                                                
# [2] "     p1    p2"                                                                          
# [3] "  \033[3m\033[38;5;246m<dbl>\033[39m\033[23m \033[3m\033[38;5;246m<dbl>\033[39m\033[23m"
# [4] "\033[38;5;250m1\033[39m  4.01  2.17"                                                    
# [5] "\033[38;5;250m2\033[39m  3.67  1.69" 

标签: rdplyrformat

解决方案


原因是有一种data.frame方法format不同于 with 的方法(在提到 'x' as 的地方format.tbl调用)。在第一种情况下,当没有时,它没有将数据更改为,而使用时,它更改为,这会导致问题pillar::format_tblObject to format or print.formattibblegroup_bytibblegroup_bytibble

library(dplyr)
df %>%
    group_by(cate) %>% 
    summarise(p1 = mean(v1), p2 = mean(v2)) %>% 
    select(-cate) %>% 
    round(2) %>% 
    as.data.frame %>% # add the `as.data.frame`
    format(nsmall = 2)

-输出

  p1   p2
1 3.02 2.86
2 3.20 3.74

在第一种情况下,检查str

> df %>%
    summarise(mean_v1 = mean(v1),
                                 mean_v2 = mean(v2)) %>% 
  round(2)%>%
  str
'data.frame':   1 obs. of  2 variables:
 $ mean_v1: num 3.09
 $ mean_v2: num 3.21

而与group_by

> df %>%
     group_by(cate) %>% 
     summarise(p1 = mean(v1), p2 = mean(v2)) %>% 
     select(-cate) %>% 
     round(2) %>%
 str
tibble [2 × 2] (S3: tbl_df/tbl/data.frame)
 $ p1: num [1:2] 3.02 3.2
 $ p2: num [1:2] 2.86 3.74

文档中也提到了?group_by

具有 grouped_df 类的分组数据框,除非 ... 和 add 的组合产生一组空的分组列,在这种情况下将返回一个 tibble。


如果我们想使用formaton tibble,请尝试使用across

df %>%
    group_by(cate) %>% 
    summarise(p1 = mean(v1), p2 = mean(v2)) %>% 
    select(-cate) %>% 
    round(2) %>%
    mutate(across(everything(), format, nsmall = 2))

-输出

# A tibble: 2 × 2
  p1    p2   
  <chr> <chr>
1 3.02  2.86 
2 3.20  3.74 

推荐阅读