R: индексы к матрице

У меня есть матричный вызов res, который изначально выглядит следующим образом:

      [,1] [,2]
[1,]     0    0
[2,]     0    0
[3,]     0    0
[4,]     0    0
[5,]     0    0
[6,]     0    0
[7,]     0    0
[8,]     0    0
[9,]     0    0
[10,]    0    0 

У меня есть матрица индексов (индексов), например:

     [,1] [,2]
 [1,]   2    3
 [2,]   7    9

Я хочу, чтобы результирующая матрица res выглядела следующим образом:

      [,1] [,2]
[1,]     0    0
[2,]     1    1
[3,]     1    1
[4,]     0    0
[5,]     0    0
[6,]     0    0
[7,]     1    1
[8,]     1    1
[9,]     1    1
[10,]    0    0 

У меня большая матрица, для перебора матрицы индексов требуется много времени. Пожалуйста, дайте мне знать, есть ли лучший подход для этого. Я надеюсь сделать что-то вроде mat[indexes,] ‹- 1. Однако это не работает, как я хотел.


person user1938809    schedule 18.06.2013    source источник


Ответы (3)


Если res, если ваша основная матрица, а indexes - это матрица индексов:

Это может помочь:

idx  <- do.call("c",apply(indexes,1,function(x){seq(x[1],x[2])}))

res[idx,] <- 1

Что касается времени, сначала создайте большую матрицу индексов:

> set.seed(42)
> indexes <- t(matrix(sort(sample(1:10000,1000)),2,500))
> head(indexes)
     [,1] [,2]
[1,]    3    4
[2,]   14   16
[3,]   23   33
[4,]   40   63
[5,]   67   74
[6,]   79   83

и время их:

> system.time(idx  <- do.call("c",apply(indexes,1,function(x){seq(x[1],x[2])})))   user  system elapsed 
  0.008   0.000   0.007 

> system.time( idx2 <- unlist( apply( indexes , 1 , FUN = function(x){ seq.int(x[1],x[2])}) ))
   user  system elapsed 
  0.004   0.000   0.002

Казалось бы, второй способ немного быстрее.

person harkmug    schedule 18.06.2013
comment
В этом случае 8-я строка не содержит единиц. Кажется, что mat[array(indexes),] ‹- 1 и mat[indexes,] ‹- 1 одинаковы. - person user1938809; 19.06.2013
comment
Но, насколько я вижу, в индексной матрице вашего примера нет числа 8 (только 2,3,7,9). - person harkmug; 19.06.2013
comment
В этом суть проблемы. Если посмотреть на получившуюся матрицу. Он очищает указывает на это. Спасибо. - person user1938809; 19.06.2013
comment
Используйте head или dput, чтобы опубликовать часть фактических матриц res и index, чтобы уточнить свой вопрос. См.: stackoverflow. com/questions/5963269/ - person harkmug; 19.06.2013
comment
Не могли бы вы привести пример в этом случае? Спасибо. - person user1938809; 19.06.2013
comment
Я пробовал idx ‹- unlist( apply( x , 1 , FUN = function(x){seq.int(x[1],x[2])}) ) раньше. Какой из них быстрее на ваш взгляд? Кажется, иногда у R заканчивается память, если матрица большая. Любой совет. Спасибо. - person user1938809; 19.06.2013

Используйте ответ на свой предыдущий вопрос, чтобы создать вектор индексов строк ridx, а затем

res[as.logical(ridx),] = 1L
person Martin Morgan    schedule 18.06.2013
comment
Да, это работает, но иногда R не хватает памяти. Я надеялся, что есть более прямой путь. - person user1938809; 19.06.2013
comment
@user1938809 user1938809 уточните - при создании Ridx? делать замену подмножества? сколько у вас памяти и насколько велики (object.size()) ваши объекты? Вышеописанная операция не должна особенно интенсивно использовать память по сравнению с другими решениями. - person Martin Morgan; 19.06.2013

РЕДАКТИРОВАТЬ: я неправильно понял, это должно помочь:

test <- matrix(rep(0,1E7), ncol=2)
Index <- matrix(sort(sample(1:(1E7*0.5), size=10000)), ncol=2, byrow=TRUE)
test[unlist(apply(Index, 1, function(x){x[1]:x[2]})),] <- 1
person rbatt    schedule 18.06.2013
comment
@user1938809 user1938809 Я попытался переосмыслить ваш вопрос и соответствующим образом отредактировал свой ответ. Если это не так, возможно, вы могли бы уточнить свою проблему. - person rbatt; 19.06.2013
comment
Во-первых, выдает ошибку. Во-вторых, я хочу, чтобы строки 2:3 и 7:9 были установлены в 1. Легко установить строки 2,3,7,9 в 1 одним вызовом. Сложная часть заключается в том, что матрица индексов дает начальные и конечные индексы для матрицы res. Спасибо. - person user1938809; 19.06.2013
comment
@user1938809 user1938809 Извините за ошибку, была опечатка. Я обновил возможное решение. - person rbatt; 19.06.2013
comment
Спасибо. Есть ли способ избежать применения? - person user1938809; 19.06.2013