首页 > 解决方案 > 在 trans_new scales 包中使用反参数

问题描述

我一直在尝试将函数 trans_new 与 scales 包一起使用,但是我无法让它正确显示标签

# percent to fold change
fun1 <- function(x) (x/100) + 1

# fold change to percent
inv_fun1 <- function(x) (x - 1) * 100



percent_to_fold_change_trans <- trans_new(name = "transform", transform = fun1, inverse = inv_fun1)


plot_data <- data.frame(x = 1:10,
                        y = inv_fun1(1:10))


# Plot raw data

p1 <- ggplot(plot_data, aes(x = x, y = y)) +
  geom_point()

# This doesn't really change the plot
p2 <- ggplot(plot_data, aes(x = x, y = y)) +
  geom_point() +
  coord_trans(y = percent_to_fold_change_trans)

p1 和 p2 是相同的,而我希望 p2 是对角线,因为我们正在反转反转函数。如果我用另一个函数(如 fun(x) x)替换 trans_new 中的反参数,我可以看到正确的转换,但标签完全关闭。关于如何定义逆参数以获得正确的标签位置的任何想法?

标签: rggplot2transform

解决方案


您不会期望像fun1改变 y 轴的外观这样的线性函数。请记住,您不是在转换数据,而是在转换 y 轴。这意味着您正在有效地改变水平网格线的位置,而不是它们所代表的值。

任何产生线性变换的函数都会导致水平网格线之间的间距固定,这就是您已经拥有的。因此情节不会改变。

我们举一个简单的例子:

plot_data <- data.frame(x = 1:10, y = 1:10)

p <- ggplot(plot_data, aes(x = x, y = y)) +
  geom_point() +
  scale_y_continuous(breaks = 1:10)

p

在此处输入图像描述

现在让我们创建一个简单的非线性变换:

little_trans <- trans_new(name      = "transform", 
                          transform = function(x) x^2,
                          inverse   = function(x) sqrt(x))

p +  coord_trans(y = little_trans)

在此处输入图像描述

请注意,y 轴上的是相同的,但由于我们应用了非线性变换,网格线之间的距离现在会发生变化。

事实上,如果我们绘制数据的转换版本,我们会得到相同的形状:

ggplot(plot_data, aes(x = x, y = y^2)) +
  geom_point() +
  scale_y_continuous(breaks = (1:10)^2)

在此处输入图像描述

从某种意义上说,这就是变换所做的一切,除了它将逆变换应用于轴标签。我们可以在这里手动完成:

ggplot(plot_data, aes(x = x, y = y^2)) +
  geom_point() +
  scale_y_continuous(breaks = (1:10)^2, labels = sqrt((1:10)^2))

在此处输入图像描述

现在,假设我做一个更复杂但线性的 x 函数:

little_trans <- trans_new(name      = "transform", 
                          transform = function(x) (0.1 * x + 20) / 3,
                          inverse   = function(x) (x * 3 - 20) / 0.1)

ggplot(plot_data, aes(x = x, y = y)) +
  geom_point() +
  coord_trans(y = little_trans)

在此处输入图像描述

它与以前没有变化。如果我们再次直接应用我们的变换,我们可以看到原因:

ggplot(plot_data, aes(x = x, y = (0.1 * y + 20) / 3)) +
  geom_point() +
  scale_y_continuous(breaks = (0.1 * (1:10) + 20) / 3)

在此处输入图像描述

显然,如果我们对轴标签进行逆变换,我们将得到 1:10,这意味着我们只会得到原始图。

这同样适用于任何线性变换,因此您得到的结果正是预期的结果。


推荐阅读