Подтвердить что ты не робот

Построение очень больших наборов данных в R

Как я могу построить очень большой набор данных в R?

Я хотел бы использовать коробку или скрипку или подобное. Все данные не могут быть помещены в память. Могу ли я поэтапно читать и вычислять резюме, необходимые для составления этих графиков? Если да, то как?

4b9b3361

Ответ 1

В дополнение к моему комментарию к Dmitri answer, функция вычисления квантилей с использованием пакета обработки больших данных ff:

ffquantile<-function(ffv,qs=c(0,0.25,0.5,0.75,1),...){
 stopifnot(all(qs<=1 & qs>=0))
 ffsort(ffv,...)->ffvs
 j<-(qs*(length(ffv)-1))+1
 jf<-floor(j);ceiling(j)->jc
 rowSums(matrix(ffvs[c(jf,jc)],length(qs),2))/2
}

Это точный алгоритм, поэтому он использует сортировку - и, следовательно, может занять много времени.

Ответ 2

Проблема в том, что вы не можете загрузить все данные в память. Таким образом, вы можете делать выборку данных, как указано ранее в @Marek. На таких огромных наборах данных вы получаете практически те же результаты, даже если вы берете только 1% данных. Для скрипичного сюжета это даст вам достойную оценку плотности. Прогрессивный расчет квантилей невозможен, но это должно дать очень приличное приближение. Это по существу то же самое, что и "рандомизированный метод", описанный в ссылке @aix.

Если вы не можете подмножить дату вне R, это можно сделать, используя соединения в сочетании с sample(). Следующей функцией является то, что я использую для отбора данных из фрейма данных в текстовом формате, когда он становится слишком большим. Если вы немного поиграете с соединением, вы можете легко преобразовать его в socketConnection или другое, чтобы прочитать его с сервера, базы данных, что угодно. Просто убедитесь, что вы открыли соединение в правильном режиме.

Хорошо, возьмите простой .csv файл, а затем следуйте за образцами функции: дробь p данных:

sample.df <- function(f,n=10000,split=",",p=0.1){
    con <- file(f,open="rt",)
    on.exit(close(con,type="rt"))
    y <- data.frame()
    #read header
    x <- character(0)
    while(length(x)==0){
      x <- strsplit(readLines(con,n=1),split)[[1]]
    }
    Names <- x
    #read and process data
    repeat{
      x <- tryCatch(read.table(con,nrows=n,sep=split),error = function(e) NULL )
      if(is.null(x)) {break}
      names(x) <- Names
      nn <- nrow(x)
      id <- sample(1:nn,round(nn*p))
      y <- rbind(y,x[id,])
    }
    rownames(y) <- NULL
    return(y)
}

Пример использования:

#Make a file
Df <- data.frame(
  X1=1:10000,
  X2=1:10000,
  X3=rep(letters[1:10],1000)
)
write.csv(Df,file="test.txt",row.names=F,quote=F)

# n is number of lines to be read at once, p is the fraction to sample
DF2 <- sample.df("test.txt",n=1000,p=0.2)
str(DF2)

#clean up
unlink("test.txt")

Ответ 3

Вы также должны посмотреть пакеты RSQLite, SQLiteDF, RODBC и biglm. Для больших наборов данных может быть полезно хранить данные в базе данных и вытаскивать только фрагменты в R. Базы данных также могут сортировать для вас, а затем вычислять квантили для отсортированных данных намного проще (тогда просто используйте квантиль для выполнения графиков).

Существует также пакет hexbin (bioconductor) для выполнения эквивалентов диаграммы рассеяния с очень большими наборами данных (возможно, все еще хотите использовать образец данных, но работает с большим образцом).

Ответ 5

Все, что вам нужно для boxplot, - это квантиль, крайние значения "вискера" и выбросы (если показано), которые легко вычисляются заранее. Взгляните на функцию boxplot.stats.

Ответ 6

Вы можете делать графики из управляемой выборки ваших данных. Например. если вы используете только 10% случайно выбранных строк, тогда boxplot на этом образце не должен отличаться от ящика для всех данных.

Если ваши данные находятся в какой-либо базе данных, вы можете создать некоторый случайный флаг (поскольку я знаю, что почти каждый движок базы данных имеет какой-то генератор случайных чисел).

Во-вторых, насколько большой ваш набор данных? Для boxplot вам нужны два столбца: переменная значения и групповая переменная. Этот пример:

N <- 1e6
x <- rnorm(N)
b <- sapply(1:100, function(i) paste(sample(letters,40,TRUE),collapse=""))
g <- factor(sample(b,N,TRUE))
boxplot(x~g)

требуется 100 МБ ОЗУ. Если N=1e7, то он использует < 1 ГБ ОЗУ (который по-прежнему управляется современной машиной).

Ответ 7

Это интересная проблема.

Коробки требуют квантилей. Вычисление квантилей на очень больших наборах данных является сложным.

Самое простое решение, которое может или не может работать в вашем случае, состоит в том, чтобы сначала скомпилировать данные и произвести графики выборки. Другими словами, читайте кучу записей за раз и сохраняйте подмножество из них в памяти (выбираете либо детерминистически, либо случайным образом). В конце создайте графики на основе данных, которые были сохранены в памяти. Опять же, насколько это жизнеспособно, очень многое зависит от свойств ваших данных.

В качестве альтернативы существуют алгоритмы, которые могут экономично и приближенно вычислять квантили в режиме "онлайн", что означает, что они представлены одним наблюдением за раз, и каждое наблюдение отображается ровно один раз. Хотя у меня ограниченный опыт работы с такими алгоритмами, я не видел никаких доступных реализаций R.

В следующем документе представлен краткий обзор некоторых соответствующих алгоритмов: Quantiles on Streams.