R: цикл по большому набору данных занимает много времени - PullRequest
2 голосов
/ 12 декабря 2011

Мне нужно применить тренд-тест Манна Кендалла в R к большому количеству (около 1 миллиона) временных рядов разных размеров.Я создал файл .txt, например, так:

1 2
1 4
1 5
2 4
2 55
3 2
3 4
3 5
3 4
3 55
...

Каждый номер первого столбца идентифицирует определенный временной ряд.Чтобы получить статистику, я использую этот код:

library(Kendall)
a=read.table("to_r.txt")
numData=1017135

for (i in 1:numData){

s1=subset(a,a$V1==i)
m=MannKendall(s1$V2)
cat(m[[1]],"  ",m[[2]], "  ", m[[3]],"  ",m[[4]],"  ", m[[5]], "\n" ,   file="monotonic_trend_checking.txt",append=TRUE)
}

Этот подход работает, но проблема в том, что он требует времени для вычислений.Временные ряды состоят максимум из 800 элементов (только несколько, остальные короче), поэтому я думаю, что основная горловина бутылки находится в цикле.Можете ли вы предложить более быстрый подход?

Ответы [ 3 ]

4 голосов
/ 12 декабря 2011

Я бы определенно посмотрел на data.table, если вы думаете, что проблема заключается в зацикливании.Недавно я написал сообщение в блоге, в котором сравниваются несколько способов циклического анализа с точки зрения производительности:

http://www.numbertheory.nl/2011/10/28/comparison-of-ave-ddply-and-data-table/

Основное сообщение заключается в том, что data.table действительно хорошо работает при количестве уникальных идентификаторов (т.е. ваше количество временных рядов) очень велико.

3 голосов
/ 12 декабря 2011

Вот очень простое решение, которое разбивает ваш набор данных на части, а затем применяет MannKendall к каждой части.

# example dataset
d <- data.frame(a=rnorm(1e6), b=rep(1:1000, each=1000))

mk <- lapply(split(d$a, d$b), MannKendall)

Это займет около десяти секунд на моем компьютере, который является достаточно мощным рабочим столом под управлением Windows.7. Результатом является список;вот первый компонент:

> mk[[1]]
tau = 0.0319, 2-sided pvalue =0.13133

Если вы хотите все это во фрейме данных:

mk <- do.call(rbind, mk)
1 голос
/ 12 декабря 2011

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

Это, конечно, предполагает, что у вас достаточно ОЗУ для хранения исходной таблицы данных и новой таблицы результатов в памяти, что, вероятно, не будет большой проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...