Создать фрейм данных всех индексов массива в R - PullRequest
1 голос
/ 06 октября 2011

Используя R, я пытаюсь построить информационный кадр из строк и чисел данной матрицы.Например, если

a   <- matrix(c(1:15), nrow=5, ncol=3)

, то я собираюсь создать кадр данных, который дает:

row col
  1   1
  1   2
  1   3
  .   .
  5   1
  5   2
  5   3

То, что я пробовал:

row <- matrix(row(a), ncol=1, nrow=dim(a)[1]*dim(a)[2], byrow=T)
col <- matrix(col(a), ncol=1, nrow=dim(a)[1]*dim(a)[2], byrow=T)
out <- cbind(row, col)
colnames(out) <- c("row", "col")

приводит к:

    row col
[1,]   1   1
[2,]   2   1
[3,]   3   1
[4,]   4   1
[5,]   5   1
[6,]   1   2
[7,]   2   2
[8,]   3   2
[9,]   4   2
[10,]  5   2
[11,]  1   3
[12,]  2   3
[13,]  3   3
[14,]  4   3
[15,]  5   3

Это не то, что я ищу, так как последовательность строк и столбцов во внезапно перевернутой, даже жесткой, я указал "byrow = T".Я не вижу, если и где я делаю ошибку, но был бы очень признателен за предложения по преодолению этой проблемы.Заранее спасибо!

Ответы [ 4 ]

3 голосов
/ 06 октября 2011

Я бы использовал expand.grid для векторов 1: ncol и 1: nrow, а затем перевернул столбцы с помощью [, 2: 1], чтобы получить их в нужном вам порядке:

> expand.grid(seq(ncol(a)),seq(nrow(a)))[,2:1]
   Var2 Var1
1     1    1
2     1    2
3     1    3
4     2    1
5     2    2
6     2    3
7     3    1
8     3    2
9     3    3
10    4    1
11    4    2
12    4    3
13    5    1
14    5    2
15    5    3
3 голосов
/ 06 октября 2011

Используйте row и col, но более непосредственно управляйте их порядком вывода, так как они возвращают соответствующие индексы вместо для входного массива. Используйте t, чтобы получить заказ не по умолчанию, который вы хотите в конце:

data.frame(row = as.vector(t(row(a))), col = as.vector(t(col(a))))
    row col
 1    1   1
 2    1   2
 3    1   3
 4    2   1
 5    2   2
 6    2   3
 7    3   1
 8    3   2
 9    3   3
 10   4   1
 11   4   2
 12   4   3
 13   5   1
 14   5   2
 15   5   3

Или, как матрица, а не data.frame:

cbind(as.vector(t(row(a))), as.vector(t(col(a))))
  [,1] [,2]
 [1,]    1    1
 [2,]    1    2
 [3,]    1    3
 [4,]    2    1
 [5,]    2    2
 [6,]    2    3
 [7,]    3    1
 [8,]    3    2
 [9,]    3    3
 [10,]   4    1
 [11,]   4    2
 [12,]   4    3
 [13,]   5    1
 [14,]   5    2
 [15,]   5    3
1 голос
/ 06 октября 2011

Возможно, вы захотите взглянуть на ?expand.grid, что точно соответствует тому, чего вы хотите достичь.

0 голосов
/ 06 октября 2011

Поскольку существует много способов убрать кошку, я добавлю еще один вариант, основанный на rep:

data.frame(row=rep(seq(nrow(a)), each=ncol(a)), col=rep(seq(ncol(a)), nrow(a)))

... но чтобы объявить "победителя", я думаю, вам нужно время для решения:

# Make up a huge matrix...
a <- matrix(runif(1e7), 1e4)

system.time( a1<-data.frame(row = as.vector(t(row(a))),
                            col = as.vector(t(col(a)))) ) # 0.68 secs

system.time( a2<-expand.grid(col = seq(ncol(a)),
                             row = seq(nrow(a)))[,2:1] ) # 0.49 secs

system.time( a3<-data.frame(row=rep(seq(nrow(a)), each=ncol(a)),
                            col=rep(seq(ncol(a)), nrow(a))) ) # 0.59 secs

identical(a1, a2) && identical(a1, a3) # TRUE

... кажется, @Spacedman предлагает самое быстрое решение!

...