【问题标题】:Indian Style thousand separator in ggplot2 chart axesggplot2图表轴中的印度风格千位分隔符
【发布时间】:2021-09-10 13:34:47
【问题描述】:

Indian style thousand separators 是这样使用的。第一个分隔符为 3 位数(千位),然后每两位分隔符。

1
10
100
1,000
10,000
1,00,000
10,00,000
1,00,00,000
10,00,00,000

我知道我可以使用 scale_y_continuous(labels = scales::comma) 更改/格式化 ggplot2 图表中的轴

但是如何根据上述印度格式更改 r ggplot2 图表轴中的千位分隔符占位符。

一个示例

library(tidyverse)
iris %>%
  mutate(Petal.Length= Petal.Length*100000) %>%
  ggplot(aes(x= Species, y = Petal.Length)) +
  geom_col() +
  scale_y_continuous(labels = scales::comma)

reprex package (v2.0.0) 于 2021-06-28 创建

【问题讨论】:

标签: r ggplot2 locale separator


【解决方案1】:

您可以定义自己的格式化函数并将其作为labels 参数提供给scale_y_continuous()。下面是一个使用基本prettyNum() 函数的示例:

library(ggplot2)

indian_comma <- function(x) {
  
  # Format the number, first dividing by 10 to place the first comma at the 
  # right point
  out <- prettyNum(x %/% 10, big.interval = 2L, big.mark = ",", scientific = FALSE)
  out <- paste0(out, x %% 10)
  
  # Switch between formatted and un-formatted depending on the size of the
  # number
  ifelse(
    x < 1000, x, out
  )
  
}

iris %>%
  mutate(Petal.Length= Petal.Length*100000) %>%
  ggplot(aes(x= Species, y = Petal.Length)) +
  geom_col() +
  scale_y_continuous(labels = indian_comma)

编辑

以下函数使用正则表达式,我认为它更好:

indian_comma <- function(x) {
  x <- prettyNum(x, scientific = FALSE)
  gsub("(?<!^)(?=(\\d{2})+\\d$)", ",", x, perl = TRUE)
}

【讨论】:

  • 我比我更喜欢你的功能,除了两件事:我会使用x %/% 10 删除最后一位数字,然后使用paste0(x, x %% 10) 将其放回原处。这样,如果有人选择了不是整数的休息时间,它仍然可以工作。
  • @BluVoxe,非常好的策略。我正在编辑您的答案以纠正那里的一个小错误。 :)
【解决方案2】:

可以设置y轴的断点,然后按照印度系统标注:

iris %>%
    mutate(Petal.Length= Petal.Length*100000) %>%
    ggplot(aes(x= Species, y = Petal.Length)) +
    geom_col() +
    scale_y_continuous(breaks = c(0,10000000,20000000),labels = c("0","1,00,00000","2,00,00,000"))

【讨论】:

  • 感谢 MonJeanJean 的快速响应,这实际上是一个不错的解决方法。 :) 已经投票了。
【解决方案3】:

这篇文章:https://stackoverflow.com/a/62037466/2554330 定义了一个函数format2()。它不能按原样工作,但通过一些小的修复,它可以工作:

format2 <- function(x, ..., big.mark = "", big.interval = c(3L, 2L), decimal.mark = ".") {
  intervene <- !is.na(x) && x > 0 && (log(abs(x), 10) >= sum(big.interval)) && nzchar(big.mark)
  cl <- match.call()
  cl[[1]] <- substitute(format)
  if (intervene) {
    cl$x <- x %/% 10^big.interval[1]
    cl$big.interval <- big.interval[2]
    bigx <- eval.parent(cl)
    cl$x <- x 
    cl$big.interval <- big.interval[1]
    mostx <- eval.parent(cl)
    mostx <- 
      substr(mostx,
             1L + nchar(x %/% 10^big.interval[1]) +
               trunc(trunc(log(abs(x %/% 10^big.interval[1]), 10L)) / big.interval[1]),
             nchar(mostx))
    return( paste0(bigx, mostx) )
  } else eval.parent(cl)
}

f <- function(x) {
  sapply(x, format2, scientific = FALSE, big.mark = ",")
}

library(tidyverse)
iris %>%
  mutate(Petal.Length= Petal.Length*100000) %>%
  ggplot(aes(x= Species, y = Petal.Length)) +
  geom_col() +
  scale_y_continuous(labels = f)

reprex package (v2.0.0) 于 2021-06-28 创建

【讨论】:

  • 感谢 user2554330 的回答。 :) 不用说我已经投票了。
猜你喜欢
  • 2019-12-24
  • 1970-01-01
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
相关资源
最近更新 更多