sec_axis transformation not working in dplyr piped ggplot.

huangapple go评论76阅读模式
英文:

sec_axis transformation not working in dplyr piped ggplot

问题

我认为问题出在 . 在 sec_axis 函数的 trans 参数中用来引用数据时可能导致错误。不确定如何解决这个问题。尝试过使用 nPatients,将其放入反引号中等,但仍未解决问题。也尝试过在 ggplot 调用周围加上大括号,这是我在其他地方看到的。我知道可以在管道外部创建 nPatients 变量并引用它,但我想知道是否有办法在管道内部解决这个问题。

英文:

I think I have an issue with the use of . to refer to data within the sec_axis trans argument of my scale_y_continuous call and I'm not sure how to resolve it.

When running the below code I get the error

Error in .$nPatients : $ operator is invalid for atomic vectors
data %>% 
      mutate(nPatients = n_distinct(clnt_label)) %>% 
      select(Description, nPatients) %>% 
      group_by(Description) %>% 
      add_count(Description, name = "Frequency") %>% 
      distinct(Description, .keep_all = TRUE) %>%
      ungroup() %>% 
      arrange(desc(Frequency)) %>%
      mutate(Percent = as.numeric(num(Frequency/nPatients * 100, digits = 1))) %>% 
      mutate(Description = factor(Description, Description), .keep = "unused") %>% 
      slice_max(n = 30, order_by = Frequency, with_ties = FALSE) %>% 
      {
        ggplot(., aes(x = Description)) +
          geom_bar(aes(y = Frequency), stat = "identity", fill = "#144ba3") +
          geom_line(aes(y = Frequency, group = 1),
                    colour = "#6c9ff0",
                    linewidth = 1.5) +
          scale_x_discrete(
            guide = guide_axis(check.overlap = TRUE, angle = 45),
            label = function(x)
              stringr::str_trunc(x, 25)
          ) +
          scale_y_continuous(
            name = "Frequency of Health Condition Code",
            sec.axis = sec_axis(~ . / max(.$nPatients) * 100, name = "Percent of Patients", guide = guide_axis()),
            expand = expansion(0.01, 0.01)
          ) +
          theme_minimal() +
          theme(
            panel.grid.major.x = element_blank(),
            axis.ticks = element_line(),
            axis.ticks.length.x = unit(0.25, "cm"),
            axis.text.x = element_text(size = 10),
            axis.title = element_text(size = 14, face = "bold"),
            axis.title.x = element_text(vjust = 0.5),
            axis.title.y.left = element_text(vjust = 1),
            axis.title.y.right = element_text(vjust = 1)
          )
      }

My assumption of what the issue is is that the . that is involved in the trans formula interferes with the use of the . to reference to the nPatients column via .$nPatients. From what I've read the scale_y_continuous evaluates in its own environment and it wouldn't contain the nPatients column of my data. However I am not certain this is the case.

I've tried using just nPatients, putting it in backticks etc. The addition of the curly braces around the ggplot call was something I saw elsewhere on SO.

While I know I could just make the nPatients variable outside of the pipe and the reference it, I'm curious if there is a way to get it to work within the pipe?

答案1

得分: 1

Your guess is right. Using the purrr style lambda function you are running into an ambiguity when using . as it is now interpreted as a vector, i.e. the column mapped on the y aes. To solve this ambiguity we could rewrite the trans function using function(x) x / max(.$nPatients) * 100 or using the base R lambda functions as \(x) x / max(.$nPatients) * 100.

使用 purrr 风格的 Lambda 函数时,你的猜测是正确的。当使用 . 时,它被解释为一个向量,即映射到 y aes 的列,从而产生了歧义。为了解决这个歧义,我们可以重新编写 trans 函数,使用 function(x) x / max(.$nPatients) * 100,或者使用基本的 R Lambda 函数,如 \(x) x / max(.$nPatients) * 100

Using a minimal reproducible example based on mtcars let's first reproduce your issue:

使用基于 mtcars 的最小可重现示例,让我们首先复现你的问题:

library(ggplot2)
library(magrittr)

mtcars %>%
{
  ggplot(., aes(hp, mpg)) +
    geom_point() +
    scale_y_continuous(sec.axis = sec_axis(~ . / max(.$mpg)))
}
#> Error in .$mpg: $ operator is invalid for atomic vectors

And now using the proposed solution:

现在使用提出的解决方案:

mtcars %>%
{
  ggplot(., aes(hp, mpg)) +
    geom_point() +
    scale_y_continuous(sec.axis = sec_axis(\(x) x / max(.$mpg)))
}

sec_axis transformation not working in dplyr piped ggplot.<!— —>

英文:

Your guess is right. Using the purrr style lambda function you are running into an ambiguity when using . as it is now interpreted as a vector, i.e. the column mapped on the y aes. To solve this ambiguity we could rewrite the trans function using function(x) x / max(.$nPatients) * 100 or the using the base R lambda functions as \(x) x / max(.$nPatients) * 100.

Using a minimal reproducible example based on mtcars let's first reproduce your issue:

library(ggplot2)
library(magrittr)

mtcars %&gt;%
  {
    ggplot(., aes(hp, mpg)) +
      geom_point() +
      scale_y_continuous(sec.axis = sec_axis(~ . / max(.$mpg)))
  }
#&gt; Error in .$mpg: $ operator is invalid for atomic vectors

And now using the proposed solution:

mtcars %&gt;%
  {
    ggplot(., aes(hp, mpg)) +
      geom_point() +
      scale_y_continuous(sec.axis = sec_axis(\(x) x / max(.$mpg)))
  }

sec_axis transformation not working in dplyr piped ggplot.<!-- -->

huangapple
  • 本文由 发表于 2023年3月21日 00:36:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75792974.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定