web-dev-qa-db-fra.com

Vectoriser une matrice

J'ai une grande matrice 2D de 1 000 x 1 000. Je souhaite le remodeler afin qu'il ne reste qu'une colonne (ou une ligne). Par exemple, si la matrice était:

A B C
1 4 7
2 5 8
3 6 9

Je veux le céder à:

1 2 3 4 5 6 7 8 9

Je n'ai pas besoin de conserver les en-têtes de colonnes, mais simplement l'ordre des données. Comment est-ce que je fais ceci en utilisant reshape2 (qui est le paquet que j'ai supposé être le plus facile à utiliser)? 


Juste pour clarifier, j'ai mentionné reshape car je pensais que c'était la meilleure façon de procéder. Je peux voir qu'il existe des méthodes plus simples qui me satisfont parfaitement.

34
djq

Je pense qu'il sera difficile de trouver une méthode plus compacte que:

c(m)
[1] 1 2 3 4 5 6 7 8 9

Toutefois, si vous souhaitez conserver une structure matricielle, cette retouche de l'attribut dim sera efficace:

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

Il y aurait des méthodes plus compactes pour obtenir le produit des dimensions mais la méthode ci-dessus souligne que l'attribut dim est un vecteur à deux éléments pour les matrices. Parmi les autres moyens d'obtenir le "9" dans cet exemple, citons:

> prod(dim(m))
[1] 9
> length(m)
[1] 9
47
42-

Une solution possible, mais sans utiliser 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
13
EDi

Allez, les gars, donnons à l'OP une solution reshape2:

> m <- matrix(c(1:9), ncol = 3)
> melt(m)$value
[1] 1 2 3 4 5 6 7 8 9

Je ne peux pas être dérangé pour tester combien il est plus lent que c (m). C'est pareil, cependant:

> identical(c(m),melt(m)$value)
[1] TRUE

[EDIT: oh heck qui je plaisante:]

> 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 
10
Spacedman

as.vector (m) devrait être un peu plus efficace que 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
3
df239

Un moyen plus simple de le faire en utilisant la fonction "sapply" (ou la même chose pourrait être fait avec la boucle 'for' aussi)

 m <- matrix(c(1:9), ncol = 3)
 (m1 <- as.numeric(sapply(1:NROW(m), function(i)(m[,i]))))
0
user36478