Векторизация матрицы
У меня есть большая 2D-матрица размером 1000 x 1000. Я хочу изменить ее так, чтобы она была одним столбцом (или строкой). Например, если матрица была:
A B C
1 4 7
2 5 8
3 6 9
Я хочу включить его в:
1 2 3 4 5 6 7 8 9
Мне не нужно сохранять заголовки столбцов, просто порядок данных. Как это сделать, используя reshape2
(который, как я полагал, был самым простым в использовании пакетом)?
Чтобы уточнить, я упомянул reshape
, поскольку я думал, что это лучший способ сделать это. Я вижу, что есть более простые методы, которыми я доволен.
Ответы
Ответ 1
Я думаю, будет сложно найти более компактный метод, чем:
c(m)
[1] 1 2 3 4 5 6 7 8 9
Однако, если вы хотите сохранить матричную структуру, то эта переработка атрибута dim будет эффективной:
dim(m) <- c(dim(m)[1]*dim(m)[2], 1)
m
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
[5,] 5
[6,] 6
[7,] 7
[8,] 8
[9,] 9
Были бы более компактные методы получения произведения размеров, но указанный выше метод подчеркивает, что атрибут dim является двухэлементным вектором для матриц. Другие способы получения "9" в этом примере:
> prod(dim(m))
[1] 9
> length(m)
[1] 9
Ответ 2
Возможное решение, но без использования reshape2:
> m <- matrix(c(1:9), ncol = 3)
> m
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> as.vector(m)
[1] 1 2 3 4 5 6 7 8 9
Ответ 3
Давай, ребята, дайте OP решение reshape2:
> m <- matrix(c(1:9), ncol = 3)
> melt(m)$value
[1] 1 2 3 4 5 6 7 8 9
Я просто не могу потрудиться, чтобы проверить, насколько он медленнее, чем c (m). Это одно и то же:
> identical(c(m),melt(m)$value)
[1] TRUE
[EDIT: О, черт возьми, кого я шучу:]
> system.time(for(i in 1:1000){z=melt(m)$value})
user system elapsed
1.653 0.004 1.662
> system.time(for(i in 1:1000){z=c(m)})
user system elapsed
0.004 0.000 0.004
Ответ 4
as.vector(m) должен быть немного более эффективным, чем c (m):
> library(rbenchmark)
> m <- diag(5000)
> benchmark(
+ vect = as.vector(m),
+ conc = c(m),
+ replications=100
+ )
test replications elapsed relative user.self sys.self user.child sys.child
2 conc 100 12.699 1.177 6.952 5.754 0 0
1 vect 100 10.785 1.000 4.858 5.933 0 0
Ответ 5
Еще один простой способ сделать это, используя функцию "sapply" (или то же самое можно сделать и с циклом "для" )
m <- matrix(c(1:9), ncol = 3)
(m1 <- as.numeric(sapply(1:NROW(m), function(i)(m[,i]))))