【问题标题】:Variable name as argument in function - ggplot R变量名称作为函数中的参数 - ggplot R
【发布时间】:2021-08-23 11:08:04
【问题描述】:

我想制作一个图表,显示相对于可以告诉我更多关于公司的变量的销售量。我希望每种产品都有不同的情节(例如各种水果:苹果、香蕉)。接下来,我想让这些图也可以轻松地用于其他公司变量。

我有一个变量的工作代码,但函数没有。它不接受它应该接受的论点。我知道这与非标准评估有关,但我无法解决此问题。

MASTERDATA%>%
  group_by(COMPANY)%>%
  summarize(AMOUNT_COMP = (sum(AMOUNT, na.rm=TRUE)),
            Type=Type,
            COMP_VAR1=COMP_VAR1)%>%
  filter(!is.na(Type)) %>%
  ggplot(aes(COMP_VAR1,AMOUNT_COMP ), na.rm = TRUE)+
  geom_point()+
  facet_wrap(~Type,nrow=4)

函数代码如下

plot_var_aantal<-function(vari){
eval(substitute(vari), MASTERDATA)
MASTERDATA%>%
  group_by(COMPANY)%>%
  summarize(AMOUNT_COMP = (sum(AMOUNT, na.rm=TRUE)),
            Type=Type,
            vari=vari)%>%
  filter(!is.na(Type)) %>%
  ggplot(aes(vari,AMOUNT_COMP ), na.rm = TRUE)+
  geom_point()+
  facet_wrap(~Type,nrow=4)

}

例如,如果我放 plot_var_aantal("people") 我只会在 x 轴上得到单词 people,所有点都在一条直线上。

数据示例

Productnr Type Amount COMPANY COMP_VAR1 COMP_VAR2
1 Apple 29 Company1 2 45
1 Pear 271 Company2 2 45
3 Apple 565 Company2 5 78
2 Banana 354 Company2 12 36
2 Pear 984 Company3 12 36
1 Banana 247 Company3 2 45
... ... ... ... ... ...

【问题讨论】:

  • 请使用dput(head(MASTERDATA))分享您的数据的一个小例子。
  • 不确定,您要做什么。也许用{{ vari }} := vari 替换vari = vari 可以解决您的问题。 aes() 中的 vari 也应该是卷曲的。
  • 为什么summarise 中有Type=Typevari=vari?他们应该怎么做?
  • @RonakShah 我在那里使用它们,因为我发现否则我没有这些变量可以在后面的行中使用。例如绘图或过滤器。
  • 如果这些变量始终相同,您可能需要将它们包含在group_by 中,或者为了保持相同的行数使用mutate 而不是summarise

标签: r dplyr


【解决方案1】:

如果您使用"people" 之类的字符串调用plot_var_aantal,则需要将vari 评估为右侧的符号!!sym(vari),在左侧您需要将其放入glue 规范中"{vari}"。以下代码应该可以工作:

plot_var_aantal<-function(vari){
  eval(substitute(vari), MASTERDATA)
  MASTERDATA%>%
    group_by(COMPANY)%>%
    summarize(AMOUNT_COMP = (sum(AMOUNT, na.rm=TRUE)),
              Type=Type,
              "{vari}" := !!sym(vari)) %>% # changed this line 
    filter(!is.na(Type)) %>%
    ggplot(aes(!! sym(vari),AMOUNT_COMP ), na.rm = TRUE) + # changed this line
    geom_point()+
    facet_wrap(~Type,nrow=4)
  
}

但是,如果没有看到您的数据,就很难弄清楚 COMP_VAR1 = COMP_VAR1 在您的 dplyr::summarise 通话中做了什么。您没有使用聚合函数(如meanpaste(..., collapse = ",")),因此整个summarise 可能不是汇总而是返回原始长度的数据。同样,"{vari}" := !!sym(vari) 行似乎没有意义(尽管vari 是字符串时的非标准评估是正确的)。

【讨论】:

    【解决方案2】:

    当将列名作为字符串传递时,您可以使用.data 代词。

    library(dplyr)
    library(ggplot2)
    
    plot_var_aantal<-function(vari){
      MASTERDATA%>%
        group_by(COMPANY)%>%
        summarize(AMOUNT_COMP = (sum(AMOUNT, na.rm=TRUE)),
                  Type=Type,
                  !!vari := .data[[vari]])%>%
        filter(!is.na(Type)) %>%
        ggplot(aes(.data[[vari]],AMOUNT_COMP), na.rm = TRUE)+
        geom_point()+
        facet_wrap(~Type,nrow=4)
    }
    
    plot_var_aantal("people")
    

    【讨论】:

      【解决方案3】:

      您可以使用aes_string(vari, 'AMOUNT_COMP') 将列名作为字符串引用,或者在summarize 语句中分配COMP_VAR1 = vari 并使用您的原始绘图代码。

      【讨论】: