Я работаю с большим вектором целых чисел в R (около 10 миллионов целых чисел), и мне нужно найти каждую отдельную пару целых чисел из этого вектора, которые отличаются на 500 или меньше, и составить гистограмму их различий (т.е. для каждая пара, вторая минус первая).
Вот совершенно не-векторизованный код для того, чтобы делать то, что я хочу, очень медленно:
# Generate some random example data
V <- round(rnorm(100) * 1000)
# Prepare the histogram
my.hist <- rep(0, 500)
names(my.hist) <- as.character(seq(1,500))
for (x1 in V) {
for (x2 in V) {
difference = x2 - x1
if (difference > 0 && difference <= 500) {
my.hist[difference] = my.hist[difference] + 1
}
}
}
(Предположим, что каждое целое число уникально, поэтому бит difference > 0
в порядке. Это разрешено, потому что на самом деле меня не волнуют случаи, когда разница равна нулю.)
Вот некоторый код, который векторизует внутренний цикл:
my.hist2 <- rep(0, 500)
names(my.hist2) <- as.character(seq(1,500))
for (x1 in V) {
differences <- V[V > x1 & V <= x1+500] - x1
difftable <- table(differences)
my.hist2[names(difftable)] = my.hist2[names(difftable)] + difftable
}
Это, безусловно, быстрее, чем первая версия. Однако даже этот вариант уже слишком медленный, когда V
содержит только 500000 элементов (полмиллиона).
Я могу сделать это без каких-либо явных циклов следующим образом:
X <- combn(V, 2)
# X is a matrix with two rows where each column represents a pair
diffs <- abs(X[2,] - X[1,])
my.hist3 <- table(diffs[diffs <= 500])
Однако матрица X будет содержать 10e6 * (10e6 - 1) / 2
или около 50 000 000 000 000 столбцов, что может быть проблемой.
Так есть ли способ сделать это без явного зацикливания (слишком медленного) или расширения матрицы всех пар (слишком большого)?
Если вам интересно, зачем мне это делать, я реализую это: http://biowhat.ucsd.edu/homer/chipseq/qc.html#Sequencing_Fragment_Length_Estimation