在自定义facet_grid函数中将列名传递给labeller

rhfm7lfc  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(99)

我正在尝试创建一个函数来创建一个定制版本的facet_grid图。我希望能够指定 Dataframe 、用作x/y和faceting变量的几个列的名称,以及一些定制标签。我能够成功创建facet_grid函数。但是我在使用标签器时遇到了问题。我把要用作分面变量的列的名称作为字符串传递给函数,但我不知道如何让标签器识别列名。
下面是一个例子。首先,这是我想使用自定义函数重新创建的图的代码:

library(dplyr)
library(ggplot2)

#sample data
data(msleep)
filtered<- msleep %>% filter(conservation %in% c('en', 'vu', 'domesticated'))

#readable labels
fancy_labels_cons <- c('domesticated' = 'Domesticated', 'en' = 'Endangered', 'vu' = 'Vulnerable')
fancy_labels_vore <- c('carni' = 'Carnivore', 'herbi'='Herbivore', 'omni'='Omnivore', 'insecti'='Insectivore')

#plot using facet grid with labels
ggplot(filtered, aes(x = sleep_total, y = awake)) + 
  geom_point() +
  facet_grid(vore ~ conservation, labeller = labeller(conservation=fancy_labels_cons, vore=fancy_labels_vore))

使用两个镶嵌面变量的花哨标签,即可得到所需的结果:

为了将其转换为函数,我将列名作为字符串传递。Facet_grid无法识别使用.datastr语法的多个变量,因此我创建了一个公式。然而,标签器无法识别列名(facetx和facety),除非我手动指定它们。如何使用列名参数来指定函数中的不同变量标签?

myfunc <- function(df, x, y, facetx, facety, xlabs, ylabs){
  #convert column-name strings to formula
  facet_func <- as.formula(paste0(facetx, ' ~ ', facety))
  ggplot(df, aes(.data[[x]], .data[[y]])) + 
    geom_point() +
    facet_grid(facet_func, 
               #this line doesn't work. Using .data[[facetx]] creates an error
               labeller = labeller(facetx=fancy_labels_cons, facety=fancy_labels_vore))
}

myfunc(filtered, x='sleep_total', y='awake', facetx='conservation', facety='vore', 
       fancy_labels_cons, fancy_labels_vore)
fcg9iug3

fcg9iug31#

@RitchieSacramento已经找到了问题的核心。你可以阅读更多关于NSE here的信息。你的错误可能是在标签机上发生的,但是在不知不觉中试图避免NSE,你已经让你的函数在其他地方变得更加复杂了。你的函数的NSE版本看起来像这样:

myfunc <- function(df, x, y, facetx, facety, labs) {
  ggplot(df, aes({{ x }}, {{ y }})) + 
    geom_point() +
    facet_grid(
      vars({{ facetx }}), 
      vars({{ facety }}),
      labeller = as_labeller(labs)
    )
}
myfunc(
  filtered, 
  x=sleep_total, 
  y=awake, 
  facetx=conservation, 
  facety=vore, 
  labs=c('domesticated' = 'Domesticated', 'en' = 'Endangered', 
         'vu' = 'Vulnerable', 'carni' = 'Carnivore', 'herbi'='Herbivore',
         'omni'='Omnivore', 'insecti'='Insectivore')
)

它产生

请注意,我对标签器做了一定的自由处理,因为我没有时间找出一种健壮的方法来标记两个不同的维度,这两个维度可能包含需要在每个维度中使用不同标签的公共值。
如果Ritchie也发布了答案,他的优先。请接受他的。

相关问题