r - R 中 facet_grid() 的 labeller() 函数内的 tidy_eval

标签 r ggplot2 facet-grid

我之前发布过这个question还有这个one这可能会为这个问题提供更多背景信息。

上下文数据:


library(tidyverse)
library(rlang)

set.seed(1)
dfr2 <- tibble(x1 = factor(sample(letters[1:3], 50, replace = T), levels=letters[1:3]),
             x2 = factor(sample(letters[1:2], 50, replace = T), levels=letters[1:2]),
             x3 = factor(sample(letters[1:3], 50, replace = T), levels=letters[1:3]),
             grpA = factor(sample(c("grp1","grp2"),50, prob=c(0.3, 0.7) ,replace=T), levels = c("grp1", "grp2")),
             grpB = factor(sample(c("grp1","grp2"),50, prob=c(0.6, 0.4) ,replace=T), levels = c("grp1", "grp2"))
             )

head(dfr2)



数据准备函数,我在其中计算用于绘图的变量以及分组变量的组总数:grp_tot



plot_data_prepr <- function(dat, groupvar, mainvar){
  
  groupvar <- sym(groupvar)
  mainvar <- sym(mainvar)
  
  plot_data <- dat %>% 
    group_by(!!groupvar) %>% 
    count(!!mainvar, .drop = F) %>% drop_na() %>% 
    mutate(pct = n/sum(n),
         pct2 = ifelse(n == 0, 0.005, n/sum(n)),
         grp_tot = sum(n),
         pct_lab = paste0(format(pct*100, digits = 1),'%'),
         pct_pos = pct2 + .02)
  
  return(plot_data)
}


数据准备功能的正常使用:



plot_data_prepr(dat = dfr2, groupvar = "grpA", mainvar = "x1")



在下面的 labeller() 函数中,我必须显式键入 'grpA' 才能使代码正常工作。虽然这会产生具有适当标签的构面标签的所需结果,但这不是我想要的,因为如果我要循环分组变量,它将阻止我动态更改分组变量:



for(mvar in names(dfr2)[1:3]) {
  
  smvar <- sym(mvar)
  
  gvar <- names(dfr2[4])
  sgvar <- sym(gvar)
  
  dd <- plot_data_prepr(dat = dfr2, groupvar = gvar, mainvar = mvar)

  lookup <- unique(dd$grp_tot)

  plusN <- function(string) {
    
    label <- paste0(string, ' (N = ',lookup,')')
    label
  }
  
    plot <- ggplot(dd, 
                   aes(x = !!smvar,y = pct2, fill = !!smvar)) +
      geom_bar(stat = 'identity') +
      ylim(0,1) +
      geom_text(aes(label=pct_lab, y = pct_pos + .02)) +
      facet_grid(as.formula(paste0(".~", gvar)), labeller = labeller(grpA = plusN))
      
    print(plot)
      
  }



相反,我希望能够使用带引号的符号 gvar ,以便我可以动态更改绘图顶部的分组变量和标签。我尝试通过在 'string' 参数上使用 enquo() 来更改 plusN() 函数,然后更改 'grpA' labeller() 函数中的 gvar,但现在分面标签根本不出现:


for(mvar in names(dfr2)[1:3]) {
  
  smvar <- sym(mvar)
  
  gvar <- names(dfr2[4])
  sgvar <- sym(gvar)
  
  dd <- plot_data_prepr(dat = dfr2, groupvar = gvar, mainvar = mvar)

  lookup <- unique(dd$grp_tot)

  plusN <- function(string) {
    
    enquo(string)
    
    label <- paste0(!!string, ' (N = ',lookup,')')
    label
  }
  
    plot <- ggplot(dd, 
                   aes(x = !!smvar,y = pct2, fill = !!smvar)) +
      geom_bar(stat = 'identity') +
      ylim(0,1) +
      geom_text(aes(label=pct_lab, y = pct_pos + .02)) +
      facet_grid(as.formula(paste0(".~", gvar)), labeller = labeller(gvar = plusN))
      
    print(plot)
      
  }

也许有人可以帮助我解决我的问题。

谢谢。

最佳答案

据我所知,解决您问题的一种方法是使用 labeller 函数,因为 facet_grid 将 df 传递给 labeller 函数,其中列df 的名称是分面变量的名称。试试这个:

试试这个:

for(mvar in names(dfr2)[1:1]) {
  
  smvar <- sym(mvar)
  
  gvar <- names(dfr2[4])
  sgvar <- sym(gvar)
  
  dd <- plot_data_prepr(dat = dfr2, groupvar = gvar, mainvar = mvar)
  
  lookup <- unique(dd$grp_tot)

  my_label <- function(x) {
    var <- names(x)[1]
    list(paste0(var, ": ", x[[var]], " (N = ", lookup, ")"))
  }
  
  plot <- ggplot(dd, 
                 aes(x = !!smvar,y = pct2, fill = !!smvar)) +
    geom_bar(stat = 'identity') +
    ylim(0,1) +
    geom_text(aes(label=pct_lab, y = pct_pos + .02)) +
    facet_grid(as.formula(paste0(".~", gvar)), labeller = my_label)
  
  print(plot)
  
}

关于r - R 中 facet_grid() 的 labeller() 函数内的 tidy_eval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62785888/

相关文章:

非时间数据的 R 运行平均值

r - 使用 MICE 包进行多次插补后合并 Cox PH 结果

python - 如何在 django url 中将一个 url 限制为仅一个 View

r - ggplot 中使用facet_grid 进行绘图的方法

r - 在 NA 的 R 中拆分单列数据框

r - 在 ggplot2 中创建一个二类分级圆?

r - ggplot2:如何交换 y 轴和右刻面带以及如何排序刻面值

r - ggplot2 scale_fill_gradient 不一致地消失

r - geom_col with facet_grid with margins=TRUE 不堆叠?

python - 防止在 relplot 中共享 y 轴