2013-07-23 2 views
0

У меня есть несколько наборов данных истории времени, собранных примерно на 500 Гц в течение 12 часов за раз.Как я могу упростить xyplot решетки с миллионами точек данных?

Я построил эти данные, используя xyplot с type="l" по шкале времени журнала, поскольку это явление в значительной степени логарифмическое распад.

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

Переключение на type="smooth" устраняет проблему рендеринга и размера файла, но сглаживание лесса резко изменяет форму линий, даже после того, как вы играли с параметрами сглаживания лёсса, поэтому я отказался от лессового сглаживания в качестве опции здесь.

Есть ли простой способ либо обработать график, чтобы упростить его, либо подпробовать данные перед графикой?

Если вы подвыбрали данные, я бы подумал, что было бы полезно сделать это в виде обратного журнала, где данные, близкие к нулю, имеют высокую частоту (используйте все 500 Гц из исходных данных), но с течением времени частота данных уменьшается (даже 0,01 Гц будет более чем достаточным около t = 12 часов) - это даст более или менее равное разрешение по графику в масштабе времени журнала.

+0

«но сглаживание лесса резко меняет форму линий»: для меня это вызывает тревожные звонки. То, что вы говорите, это в основном то, что вы подходите под модель, но что модель подходит очень плохо. Либо ваши предварительные представления о ваших данных должны быть скорректированы, либо вы должны настроить свою модель (изменить некоторые настройки лёсса, использовать другую гладкость и т. Д.). – joran

+0

@joran вы абсолютно правы. Вот почему я отказался от лессового сглаживания. Я отредактирую, чтобы уточнить. – mac

+0

Я просто говорю, что гладкий плавник - это правильный путь, вы еще не нашли подходящего. Вы можете попробовать сплайны, или вы можете переключиться на ggplot, что обеспечивает несколько более легкий интерфейс для более широкого массива сглаживания (в частности, 'gam'). – joran

ответ

1

После того, как вы попробовали type="spline" и снова недовольны тем, насколько он меняет форму моих данных, я решил пойти с подвыборным подходом, где я уменьшил плотность данных до построения графика.

Функция, которую я написал, будет подбирать по шкале журнала, чтобы «разрешение графика» было более или менее постоянным.

## log.subsample(data,time,n.per.decade) 

## subsamples a time-sampled data.frame so that there are no more than 
## n.per.decade samples in each decade. 

## usage 
## data: data.frame, the data frame object, must contain a column with 
##  times 
## 
## time: charater, the name of the data frame column with the time 
##  values 
## n.per.decade: the max number of rows per decade of time 

## value 
## returns a data.frame object with the same columns as data, 
## subsampled such that there are no more than n.per.decade rows in 
## each decade of time. Any rows in data with time < 0 are dropped. 

log.subsample <- function(data,time,n.per.decade){ 
    time.col <- grep(x=colnames(data),pattern=time) 
    min.time <- min(data[,time.col]) 
    if(min.time < 0){ 
     data <- data[data[,time.col]>0,] 
     min.time <- min(data[,time.col]) 
     droplevels(data) 
    } 
    max.time <- max(data[,time.col]) 
    stopifnot(max.time > 0) 
    min.decade <- floor(log10(min.time)) 
    max.decade <- ceiling(log10(max.time)) 

    time.seq <- seq(from=min.decade, to=max.decade, by=1/n.per.decade) 
    time.seq <- 10^time.seq 
    for(i in 1:length(time.seq)){ 
     tmp <- which(data[,time.col] >= time.seq[i])[1] 
     if(!is.na(tmp)){ 
      if(!exists("indices.to.keep")){ 
       indices.to.keep <- tmp 
      } 
      else{ 
       indices.to.keep <- c(indices.to.keep,tmp) 
      } 
     } 
    } 
    indices.to.keep <- unique(indices.to.keep) 
    result <- data[indices.to.keep,] 
    result <- droplevels(result) 
    return(result) 
} 

Единственная проблема здесь в том, что если есть какая-либо «группа» в данных для построения графика, эта функция подвыборки должна быть запущена по каждой группе в отдельности, а затем кадр данных должна быть построен, чтобы передать к xyplot()

было бы замечательно, если бы кто-то может сказать мне, если это возможно «внедрить» эту субдискретизации процедуру в xyplot() вызова как-то так, что он будет вызываться для каждой отдельной группы данных, в свою очередь, исключает необходимость разбить данные вверх, запустить подпрограмму подвыборки и сместить данные обратно до вызова xyplot()

+0

Да, если вы напишете функцию панели, но это немного сложно. –

+0

@BenBolker Я понял, что это будет так. У меня есть некоторый опыт работы с функциями панели, но не для обработки самих данных. Не могли бы вы указать мне на какие-нибудь примеры? – mac

+0

Например: 'd <- data.frame (x = runif (1000), y = runif (1000), f = sample (1: 6, replace = TRUE, size = 1000)); библиотека (решетки); графика XY (у ~ х | F, данные = д); xyplot (y ~ x | f, data = d, panel = function (x, y, ...) {x <- x [1:10]; y <- y [1:10]; panel.xyplot (x , y, ...)}) 'В качестве альтернативы вы можете использовать' plyr :: ddply' для автоматизации цикла split-apply-comb ... –

Смежные вопросы