如何更改 ggplot2 中因子变量的小数位?

How to change decimal places of a factor variable in ggplot2?

提问人:Ahsk 提问时间:7/26/2023 更新时间:7/26/2023 访问量:67

问:

我想将 x 和 y 轴上的小数位更改为两个而不是一个。例如,我需要而不是 .问题是我的 x 轴和 y 轴是因子变量,所以我似乎无法更改小数位。我尝试转换和数字,但得到了 NA。17.1117.1mean_temptotal_count

这是热图

enter image description here

这是用于创建上图的可重现示例

df <- structure(
  list(
    total_count = c(
      10L,
      0L,
      15L,
      0L,
      20L,
      0L,
      0L,
      50L,
      0L,
      6L,
      1L,
      10L,
      7L,
      0L,
      0L,
      29L,
      0L,
      2L,
      11L,
      3L,
      0L,
      12L,
      0L,
      30L,
      0L,
      0L,
      29L,
      44L,
      10L,
      5L,
      2L,
      145L,
      0L,
      70L
    ),
    mean_temp = c(
      18.87,
      18.87,
      18.87,
      18.87,
      18.87,
      18.87,
      18.87,
      18.87,
      18.87,
      21.85,
      21.85,
      21.85,
      21.85,
      21.85,
      21.85,
      21.85,
      21.85,
      21.85,
      17.11,
      17.11,
      17.11,
      17.11,
      17.11,
      17.11,
      17.11,
      17.11,
      18.82,
      18.82,
      18.82,
      18.82,
      18.82,
      18.82,
      18.82,
      18.82
    ),
    lwd_duration = c(
      64.32,
      64.32,
      64.32,
      64.32,
      64.32,
      64.32,
      64.32,
      64.32,
      64.32,
      104.2,
      104.2,
      104.2,
      104.2,
      104.2,
      104.2,
      104.2,
      104.2,
      104.2,
      53.53,
      53.53,
      53.53,
      53.53,
      53.53,
      53.53,
      53.53,
      53.53,
      60.43,
      60.43,
      60.43,
      60.43,
      60.43,
      60.43,
      60.43,
      60.43
    )
  ),
  row.names = c(NA,-34L),
  class = c("tbl_df", "tbl", "data.frame"),
  na.action = structure(
    c(
      `4` = 4L,
      `5` = 5L,
      `6` = 6L,
      `7` = 7L,
      `8` = 8L,
      `9` = 9L,
      `78` = 78L,
      `87` = 87L,
      `96` = 96L,
      `105` = 105L,
      `114` = 114L,
      `123` = 123L,
      `132` = 132L,
      `141` = 141L,
      `150` = 150L,
      `159` = 159L,
      `168` = 168L,
      `177` = 177L,
      `186` = 186L,
      `849` = 849L,
      `850` = 850L,
      `851` = 851L,
      `852` = 852L,
      `891` = 891L,
      `892` = 892L,
      `893` = 893L,
      `894` = 894L,
      `921` = 921L,
      `922` = 922L,
      `923` = 923L,
      `924` = 924L,
      `937` = 937L,
      `938` = 938L,
      `939` = 939L,
      `940` = 940L,
      `969` = 969L,
      `970` = 970L,
      `971` = 971L,
      `972` = 972L,
      `985` = 985L,
      `986` = 986L,
      `987` = 987L,
      `988` = 988L,
      `1017` = 1017L,
      `1018` = 1018L,
      `1019` = 1019L,
      `1020` = 1020L,
      `1033` = 1033L,
      `1034` = 1034L,
      `1035` = 1035L,
      `1036` = 1036L
    ),
    class = "omit"
  )
)

用于创建图形的代码

dat2 <-
  df %>%
  as_tibble() %>%
  mutate(
    mean_temp = cut_interval(mean_temp, n = 10),
    total_count = cut_interval(total_count, n = 10),
  ) %>%
  group_by(mean_temp, total_count) %>%
  summarize(lwd_duration = mean(lwd_duration))
#> `summarise()` has grouped output by 'mean_temp'. You can override using the
#> `.groups` argument.

ggplot(dat2, aes(mean_temp, total_count)) +
  geom_tile(aes(fill = lwd_duration)) +
  geom_text(aes(label = round(lwd_duration, 1))) +
  scale_fill_gradient(low = "white", high = "red")

注意:如果无法更改小数位,我也会对整数感到满意。主要目标是确保 x 轴和 y 轴上显示的值之间的一致性和一致性,因为完整的图形包含一位和两位小数(由于空间限制,我无法在此处粘贴整个数据集)。谢谢

R ggPlot2 DPLYR 可视化 数据操作

评论

1赞 langtang 7/26/2023
您可以查看调用的参数?dig.labcut_interval()
0赞 Ahsk 7/26/2023
@langtang我应该设置什么值?我试过了,但在轴上得到了非常大的数字。谢谢dig. lab0.2
0赞 Billy34 7/26/2023
2 ?(小数点后 2 位)
0赞 Ahsk 7/26/2023
也尝试了 2 个。同样的问题
0赞 langtang 7/26/2023
它不是很好,因为你必须设置为 4,因为它是总位数,而不是小数位。此外,它不使用固定格式,因此不会变为整数(它仍然是整数)1010.00

答:

1赞 Allan Cameron 7/26/2023 #1

为了完全控制外观,我可能会使用字符串解析。这包括删除括号,从技术角度来看,括号很有帮助,但在绘图上通常会造成混淆或混乱。

library(tidyverse)

dat2 %>%
  ungroup() %>%
  separate(mean_temp, into = c("a", "b"), sep = ",") %>%
  separate(total_count, into = c("c", "d"), sep = ",") %>%
  mutate(across(1:4, ~as.numeric(str_remove(., "\\[|\\(|\\]|\\)")))) %>%
  mutate(across(1:4, ~ sprintf("%.2f", .))) %>%
  mutate(mean_temp = paste(a, b, sep = " - ")) %>%
  mutate(total_count = paste(c, d, sep = " - ")) %>%
  dplyr::select(c(6, 7, 5)) %>%
  ggplot(aes(mean_temp, total_count)) +
  geom_tile(aes(fill = lwd_duration)) +
  geom_text(aes(label = round(lwd_duration, 1))) +
  scale_fill_gradient(low = "white", high = "red")

enter image description here

评论

1赞 Allan Cameron 7/26/2023
@Ahsk我知道 - 只是图是用来说明的,这是一个微妙之处,在展示你的 .data 时通常可以跳过
1赞 langtang 7/26/2023 #2

您可以将 (in ) 设置为足够高的整数,例如 或 。然后,您可以随后使用这个小函数来标准化dig.labcut_intevals()45cut_interval

standardize_cut_levels <- function(l, dig=2) {
  sapply(l, \(s) {
    m = gregexpr("\\d+\\.?\\d{0,}",s)
    m = regmatches(s,m)[[1]]
    r = sub(m[1], trimws(sprintf(paste0("%9.", dig, "f"), as.numeric(m[1]))),s)
    sub(m[2], trimws(sprintf(paste0("%9.", dig, "f"), as.numeric(m[2]))),r)
  })
}

现在,在创建之后,只需像这样调用此函数:dat2

levels(dat2$mean_temp) <- standardize_cut_levels(levels(dat2$mean_temp))
levels(dat2$total_count) <- standardize_cut_levels(levels(dat2$total_count))

现在,您的绘图代码将生成以下内容:

enter image description here

评论

0赞 Ahsk 7/26/2023
成功了。谢谢你对他的帮助。