Обертывание функции построения графика R (или ggplot2) для предотвращения построения больших наборов данных

#r #plot #ggplot2 #bigdata

#r #построение #ggplot2 #bigdata

Вопрос:

Вместо того, чтобы спрашивать, как строить большие наборы данных, я хочу обернуть plot так, чтобы код, который создает много графиков, не забивался при построении большого объекта. Как я могу обернуть plot очень простым способом, чтобы сохранить всю его функциональность, но сначала проверить, является ли передаваемый объект слишком большим?

Этот код работает для очень простых вызовов plot , но ему не хватает той же общности, plot что и (см. Ниже).

 myPlot <- function(x, ...){
    isBad <- any( (length(x) > 10^6) || (object.size(x) > 8*10^6) || (nrow(x) > 10^6) )
    if(is.na(isBad)){isBad = FALSE}
    if(isBad){
        stop("No plots for you!")
    }
    return(plot(x, ...))
}

x = rnorm(1000)
x = rnorm(10^6   1)

myPlot(x)
  

Пример, в котором это не удается:

 x = rnorm(1000)
y = rnorm(1000)
plot(y ~ x)
myPlot(y ~ x)
  

Есть ли какой-нибудь простой способ переноса plot , позволяющий выполнить эту проверку отображаемых данных, при этом все еще проходя через все аргументы? Если нет, то как насчет ggplot2 ? Я сторонник равных возможностей. (В тех случаях, когда набор данных большой, я буду использовать hexbin, подвыборку, графики плотности и т. Д., Но здесь это не главное.)


Примечание 1: При тестировании идей я рекомендую тестировать для размера> 100 (или, например, устанавливать переменную myThreshold <- 1000 ), а не для размера> 1 м — в противном случае будет много проблем при медленном построении графика. 🙂

Ответ №1:

Проблема, с которой вы сталкиваетесь, заключается в том, что в текущем кодировании myplot() предполагается x , что это объект данных, но затем вы пытаетесь передать ему формулу. R plot() достигает этого с помощью методов — когда x это формула, plot.formula() метод отправляется вместо базового plot.default() метода.

Вам нужно сделать то же самое:

 myplot <- function(x, ...)
    UseMethod("myplot")

myplot.default <- function(x, ....) {
    isBad <- any((length(x) > 10^6) || (object.size(x) > 8*10^6) || 
                    (nrow(x) > 10^6))
    if(is.na(isBad)){isBad = FALSE}
    if(isBad){
        stop("No plots for you!")
    }
    invisible(plot(x, ...))
}

myplot.formula <- function(x, ...) {
    ## code here to process the formula into a data object for plotting
    ....
    myplot.default(processed_x, ...)
}
  

Вы можете украсть код из plot.formula() , чтобы использовать в коде, необходимом для обработки x в объекте. Кроме того, вы можете создать свою собственную, следуя стандартным нестандартным правилам оценки (PDF).

Комментарии:

1. 1 За понимание того, что происходит, и за очень полезный указатель на стандартную нестандартную ссылку. Можете ли вы уточнить, где я могу найти код для plot.formula ? Я полагаю, что любой код, который извлекает объекты из формулы, будет работать, поэтому я тоже ищу это.

2. @Iterator graphics:::plot.formula или getAnywhere(plot.formula) покажет код. methods(plot) покажет, какие методы S3 доступны для общего построения графика. Обратите внимание, что plot.formula * в выходных данных отображается символ from methods() , указывающий, что сама функция не экспортируется из пространства имен; вместо этого она зарегистрирована как метод S3 для отправки.

3. @Iterator Для извлечения объектов из формулы стандартные нестандартные правила являются преобладающей парадигмой в R — plot.формула, по-видимому, использует эту идиому, хотя она усложняется необходимостью в этой функции также получать информацию об именах объектов, извлеченных из формулы, для обозначения осей графика. Смотрите PDF-файл, на который я ссылался, для получения более простых сведений об основных шагах, необходимых для извлечения объектов. Вам также понадобится больше аргументов в методе формулы, чем я показал. Снова см. PDF для аргументов, необходимых для полного использования этой идиомы.