65-R茶话会14-柱状图用col还是bar,你可以省一点空间

2021-12-17 11:01:51 浏览数 (1)

参考:

geom_col or geom_bar

二者唯一的区别在于,col 的stat 参数是identity。因此如果使用geom_bar 指定stat = "identity",二者是没有区别的。

指定了这个参数意味着什么呢?

意味着我们可以给y 指定一个自定义的数值,而非让ggplot 函数转化我们的数据框去计数。

比如你有一个数据:

代码语言:javascript复制
iris2 <- iris
iris2$group <- sample(c("a","b","c"), 150, replace = T)
> str(iris2)
'data.frame': 150 obs. of  6 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ group       : chr  "b" "a" "b" "c" ...

如果你进行如下绘图:

代码语言:javascript复制
ggplot(iris2)   geom_bar(aes(Species, fill = group))

但其实我们完全可以自己计算一个数据框:

代码语言:javascript复制
> iris2_count <- iris2 %>% 
    group_by(Species, group) %>%
    summarise(count = n())
`summarise()` has grouped output by 'Species'. You can override using the `.groups` argument.
> iris2_count
# A tibble: 9 x 3
# Groups:   Species [3]
  Species    group count
  <fct>      <chr> <int>
1 setosa     a        18
2 setosa     b        18
3 setosa     c        14
4 versicolor a        12
5 versicolor b         9
6 versicolor c        29
7 virginica  a        13
8 virginica  b        22
9 virginica  c        15

接下来直接用geom_col 就好了:

代码语言:javascript复制
ggplot(iris2_count)   geom_col(aes(x = Species, y = count, fill = group), 
                         position = "dodge")

节约了多少空间呢

代码语言:javascript复制
> object.size(iris2)
8728 bytes
> object.size(iris2_count)
4816 bytes

这还不够刺激。我们翻个倍吧,100倍如何?

代码语言:javascript复制
enlargeDf <- function(df,df2,n) {
  if (n > 1){
    df <- rbind(df, df2)
    enlargeDf(df,df2,n - 1)
  } else {
    df <- df
  }
}
iris_big <- enlargeDf(iris2, iris2, 100)
dim(iris_big)
[1] 15000     6

画个图:

代码语言:javascript复制
iris_big_count <- iris_big %>% 
  group_by(Species, group) %>%
  summarise(count = n())

a1 <- object.size(iris_big_count)
a2 <- object.size(iris_big)
aa <- data.frame(
  V1 = c("a1","a2"),
  V2 = c(as.numeric(a1), as.numeric(a2))
)

ggplot(aa, aes(V1, V2, label = V2, fill = V1))   
  geom_col()   
  geom_text(vjust = -0.8) 

这里还仅仅是一万五千行数据框,动辄十几万或者上百万的数据框呢?

转换后的文件不仅方便我们读取和传送,而且从数据的阅读直观程度来看,统计转化的结果也更容易传播。

0 人点赞