Передача данных и имен столбцов в ggplot через другую функцию

Я сразу перейду к примеру и прокомментирую послесловия:

cont <- data.frame(value = c(1:20),variable = c(1:20,(1:20)^1.5,(1:20)^2),group=rep(c(1,2,3),each=20))

   value   variable group
1       1  1.000000     1
2       2  2.000000     1
3       3  3.000000     1
#... etc.

#ser is shorthand for "series".
plot_scat <- function(data,x,y,ser) {
        ggplot(data,aes(x=x,y=y,color=factor(ser)))+geom_point()
}

plot_scat(cont,value,variable,group)
#This gives the error:
#Error in eval(expr,envir,enclose) : object 'x' not found

Теперь я знаю, что в ggplot2 есть известная ошибка, при которой aes () будет искать только в глобальной среде, а не в локальной. Следуя совету: Использование ggplot () в другой функции в R, пробовал другой путь.

plot_scat <- function(data,x,y,ser) {
        #environment=environment() added
        ggplot(data,aes(x=x,y=y,color=factor(ser)),environment=environment())+geom_point()
}

plot_scat(cont,value,variable,group)
#This gives the error:
#Error in eval(expr,envir,enclos) : object 'value' not found
#In addition: Warning message:
#In eval(expr,envir,enclos) : restarting interrupted promise evaluation

Я не знаю, что означает эта последняя строчка. Если я позвоню: ggplot (cont, aes (x = value, y = variable, color = group)) + geom_point ()

Я получаю график, которого вы ожидаете. В командной строке aes () ищет имена переменных в ggplot (), но не делает этого в вызове функции. Итак, я попытался изменить свой звонок:

plot_scat(cont,cont$value,cont$variable,cont$group)

Это дает мне то, что я хочу. Итак, я добавляю следующий уровень сложности:

plot_scat <- function(data,x,y,ser) {
        #added facet_grid
        ggplot(data,aes(x=x,y=y,color=factor(ser)),environment=environment())+geom_point()+
        facet_grid(.~ser)
}

plot_scat(cont,cont$value,cont$variable,cont$group)
#This gives the error:
#Error in layout_base(data, cols, drop = drop):
#   At least one layer must contain all variables used for facetting

Я думал об этом, что ser на самом деле cont $ group, что хорошо для использования в aes (), но при передаче в facet_grid теперь фрейм данных с одним столбцом без информации о значениях и переменных. Согласно странице справки, facet_grid не принимает аргумент «data =», поэтому я не могу использовать facet_grid (data = data ,. ~ ser), чтобы обойти это. Я не знаю, что делать дальше.

Это чрезвычайно простой пример, но долгосрочная цель состоит в том, чтобы иметь функцию, которую я могу дать неграмотным в R людям в моем офисе и сказать «дайте ей имя фрейма данных, имена столбцов и столбец, который вы хотите разделить. и из него получатся красивые сюжеты ". Он также станет намного более сложным, с очень индивидуализированной темой, которая не имеет отношения к моим проблемам.


person SatelliteEyes    schedule 04.12.2015    source источник


Ответы (2)


Если вы не хотите передавать свои переменные (имена столбцов) в виде строк / кавычек, тогда используйте один из подходов, которые я пробовал (см. Также здесь) должен был использовать match.call() и eval. Он также работает с фасетированием (как и в вашем случае):

library(ggplot2)

cont <- data.frame( value = c(1:20),
                    variable = c(1:20, (1:20) ^ 1.5, (1:20) ^ 2),
                    group = rep(c(1, 2, 3), each = 20))


plot_scat <- function(data, x, y, ser) {
    arg <- match.call()
    ggplot(data, aes(x = eval(arg$x),
                     y = eval(arg$y),
                     color = factor(eval(arg$ser)))) +
        geom_point() +
        facet_grid(. ~ eval(arg$ser))
}

# Call your custom function without quoting the variables
plot_scat(data = cont, x = value, y = variable, ser = group)

введите здесь описание изображения

Чтобы понять, что делает match.call(), попробуйте запустить следующее:

plot_scat <- function(data, x, y, ser) {
  str(as.list(match.call()))
}
plot_scat(cont, value, variable, group)
#> List of 5
#>  $     : symbol plot_scat
#>  $ data: symbol cont
#>  $ x   : symbol value
#>  $ y   : symbol variable
#>  $ ser : symbol group

Создано 10 января 2019 г. пакетом REPEX (v0.2.1)


Или другой обходной путь, но на этот раз с передачей имен столбцов в кавычках пользовательской функции построения графика используется get():

plot_scat <- function(data, x, y, ser) {
    ggplot(data, aes(x = get(x),
                     y = get(y),
                     color = factor(get(ser)))) +
      geom_point() +
      facet_grid(. ~ get(ser))
  }

plot_scat(data = cont, x = "value", y = "variable", ser = "group")
person Valentin    schedule 10.01.2019

Вы можете использовать aes_string () вместо aes () и передавать имена столбцов в виде строк.

plot_scat <- function(data,x,y,ser) {
ser_col = paste("factor(",ser,")")
ggplot(data,aes_string(x=x,y=y,col=ser_col))+geom_point()+facet_grid(as.formula(sprintf('~%s',ser)))
}

plot_scat(cont,"value","variable","group") 

facet_grid требуется формула, поэтому вы можете использовать as.formula для синтаксического анализа строки в формулу.

person user5219763    schedule 04.12.2015