Реализация параметров геометрии из пользовательской функции

Я склоняюсь к невероятно сложным цифрам ggplot с большим количеством настроек, поэтому я, естественно, добавляю их в свой код как функции, чтобы я мог их легко использовать повторно. Проблема возникает, когда я хочу использовать одну из моих пользовательских функций, но слегка ее настраиваю, например. удаление или добавление эстетики к геометрии, которую я уже определил внутри функции. Мои параметры для этого:

  • Создайте почти дублируемую функцию, но с добавленным конкретным изменением, и имя функции изменилось, чтобы отразить это или

  • Добавьте аргументы функции, которые изменяют способ построения ggplot внутри функции

Я стараюсь и выбираю 2. насколько могу, потому что это явно уменьшает количество избыточности и беспорядка в моих сценариях.

Однако бывают случаи, когда 2. почти вырождается в 1. внутри функции, заставляя меня повторять целые геомные функции, содержащие несколько аргументов. Я приведу очень простой пример, не забывая, что функции, которые у меня есть, намного усложняют и ценят размышления, которые я здесь делаю:

gg_custom_point <- function(df, xvar, yvar, gvar=NA){
    g <- ggplot(df)

    if(is.na(gvar)){
        # do geom without colour
        g <- g + geom_point(aes_string(x=xvar, y=yvar))
    }
    else{
        # do geom with colour - mostly redundant code
        g <- g + geom_point(aes_string(x=xvar, y=yvar, colour=gvar))
    }
    return(g)
}

# I can use the same function to make slightly different custom plots
gg_custom_point(mtcars, "wt", "mpg")
gg_custom_point(mtcars, "wt", "mpg", "qsec")

Проблема заключается в том, что мне пришлось повторно указать целое geom_point вместо того, чтобы просто добавить эстетику. Проблема избыточности еще хуже, если я когда-либо захочу настроить множественную эстетику для одной геометрии - мне нужно ввести геометрию, содержащую все комбинации эстетики, которые могут быть использованы в данных аргументах.

Я мог бы сделать это:

g <- g + geom_point(aes_string(x=xvar, y=yvar))
if(!is.na(gvar)){
    # Add to the global aesthetic - no need to retype the whole geom
    g <- g + aes_string(colour=gvar)
}

Но это не масштабируется для нескольких геометров с использованием нескольких источников данных, так как для всех геометров потребуется использовать эту эстетику цвета и столбец gvar.

Есть ли способ легко добавлять эстетику к определенным геомам, которые уже добавлены в объект ggplot? Альтернативно, есть ли лучший способ использования функций ggplot2 и геометров внутри пользовательской функции?

Ответ 1

Я не знаю, действительно ли это вам нужно - это упрощает ваш пример выше, устанавливая аргументы NULL вместо NA. Он не охватывает все параметры, но устраняет необходимость в операторах if, поскольку аргумент, установленный в NULL, не выдает ошибки, например NA. Также должен быть масштабируемым для нескольких геометров с дополнительными аргументами функции.

gg_custom_point <- function(dat, xvar, yvar, gvar=NULL ,grp=NULL , ... ,
                                                 mytheme=NULL) 
 {
  g <- ggplot() +  
  geom_point(data=dat, aes_string(x=xvar, y=yvar, colour=gvar, group=grp), ...) +
  mytheme

  return(g)
  }


gg_custom_point(mtcars, "wt", "mpg")
gg_custom_point(mtcars, "wt", "mpg", "qsec")
gg_custom_point(mtcars, "wt", "mpg", "qsec" , size=10)
gg_custom_point(mtcars, "wt", "mpg", "qsec" , size=10 , mytheme=theme_bw())