2016-01-15 6 views
1

Мотивация: В настоящее время я пытаюсь переосмыслить свое кодирование, чтобы исключить возможность петель, где это возможно. Следующая проблема может быть легко решена с помощью обычных for-loops, но мне было интересно, дает ли R возможность использовать семейство приложений для облегчения проблемы.Повторное подмножество одной и той же матрицы, применяемое в R

Проблема: У меня есть матрица, скажем X (n x k матрица) и две матрицы пуска и останова индексов, называется index.starts и index.stops соответственно. Они имеют размер n x B и содержат это значение index.stops = index.starts + m для некоторого целого числа m. Каждая пара index.starts[i,j] и index.stops[i,j] необходимы для подмножества X как X[ (index.starts[i,j]:index.stops[i,j]),]. I.e., они должны выбрать все строки X в своем диапазоне индексов. Могу ли я решить эту проблему, используя одну из применяемых функций?

Приложение: (Не обязательно важно для понимания моей проблемы.) В случае, если вас это интересует, это необходимо для приложения для начальной загрузки с блоками в приложении временных рядов. Исходный образец представляет X. index.starts отбирается как replicate(repetitionNumber, sample.int((n-r), ceiling(n/r), replace=TRUE)) и index.stops получается как index.stop = index.starts + m. В конце концов я хочу собрать ряд из X. В частности, я хочу переделать repetitionNumber раз m блоки длиной r от X.

Пример:

#generate data 
n<-100 #the size of your sample 
B<-5 #the number of columns for index.starts and index.stops 
    #and equivalently the number of block bootstraps to sample 
k<-2 #the number of variables in X 
X<-matrix(rnorm(n*k), nrow=n, ncol = k) 

#take a random sample of the indices 1:100 to get index.starts 
r<-10 #this is the block length 
#get a sample of the indices 1:(n-r), and get ceiling(n/r) of these 
#(for n=100 and r=10, ceiling(n/r) = n/r = 10). Replicate this B times 
index.starts<-replicate(B, sample.int((n-r), ceiling(n/r), replace=TRUE)) 
index.stops<-index.starts + r 

#Now can I use apply-functions to extract the r subsequent rows that are 
#paired in index.starts[i,j] and index.stops[i,j] for i = 1,2,...,10 = ceiling(n/r) and 
#j=1,2,3,4,5=B ? 
+0

Можете ли вы дать минимальный рабочий пример с некоторыми (поддельными) данными, например, для n = 3 и k = 4 или что-то вроде этого? Делает это легче понять и решить ... – David

+1

Эй, Дэвид, надеюсь, это поможет вам! –

+0

Возможно, вам нужно «Map («: », index.starts, index.stops)' и подмножество «X» соответственно? –

ответ

1

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

Мой подход использует (несколько) * apply-functions. Первый lapply «петли» над случаями 1: B, где он сначала вычисляет начальную и конечную точки, которые объединены в take.rows (с номерами подмножества). Далее, inital-матрица подмножается take.rows (и возвращается в списке). В качестве последнего шага стандартное отклонение берется для каждого столбца подмножеств (как фиктивная функция).

Код (с тяжелым комментирование) выглядит следующим образом:

# you can use lapply in parallel mode if you want to speed up code... 
lapply(1:B, function(i){ 
    starts <- sample.int((n-r), ceiling(n/r), replace=TRUE) 
    # [1] 64 22 84 26 40 7 66 12 25 15 
    ends <- starts + r 

    take.rows <- Map(":", starts, ends) 
# [[1]] 
# [1] 72 73 74 75 76 77 78 79 80 81 82 
# ... 

    res <- lapply(take.rows, function(subs) X[subs, ]) 
# res is now a list of 10 with the ten subsets 
# [[1]] 
# [,1]  [,2] 
# [1,] 0.2658915 -0.18265235 
# [2,] 1.7397478 0.66315385 
# ... 

    # say you want to compute something (sd in this case) you can do the following 
    # but better you do the computing directly in the former "lapply(take.rows...)" 
    res2 <- t(sapply(res, function(tmp){ 
    apply(tmp, 2, sd) 
    })) # simplify into a vector/data.frame 
# [,1]  [,2] 
# [1,] 1.2345833 1.0927203 
# [2,] 1.1838110 1.0767433 
# [3,] 0.9808146 1.0522117 
# ... 
    return(res2) 
}) 

ли это момент вы в правильном направлении/дает ответ?

+1

Дэвид, это здорово! Я даже не думаю, что это сложно, и теперь команда Map() делает много смысла, я вижу это. Мне очень нравится решение, с помощью которого вы получаете res/res2! Благодарим вас за чрезмерное комментирование, это действительно помогло мне! :) –

+0

Всегда приятно. Последнее, если вы хотите ускорить код, вы можете использовать 'snowfall' и' sfClusterApplyLB' для выполнения параллельно (посмотрите статью, которую я написал ранее: https://datashenanigan.wordpress.com/ 2015/09/23/имитируя-backtests в наличии возвраты-используя-Монте-Карло-и-снегопада-в-параллельно /). – David

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