Построение очень больших наборов данных в R
Как я могу построить очень большой набор данных в R?
Я хотел бы использовать коробку или скрипку или подобное. Все данные не могут быть помещены в память. Могу ли я поэтапно читать и вычислять резюме, необходимые для составления этих графиков? Если да, то как?
Ответы
Ответ 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) для выполнения эквивалентов диаграммы рассеяния с очень большими наборами данных (возможно, все еще хотите использовать образец данных, но работает с большим образцом).
Ответ 4
Вы можете поместить данные в базу данных и вычислить квантили, используя SQL. См.: http://forge.mysql.com/tools/tool.php?id=149
Ответ 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.