英文:
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)))
}
<!— —>
英文:
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 %>%
{
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)))
}
<!-- -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论