J'écris du code R pour créer une matrice carrée. Donc, mon approche est la suivante:
Ma question est très simple: quel est le meilleur moyen de pré-allouer cette matrice? Jusqu'ici, j'ai deux façons:
> x <- matrix(data=NA,nrow=3,ncol=3)
> x
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] NA NA NA
ou
> x <- list()
> length(x) <- 3^2
> dim(x) <- c(3,3)
> x
[,1] [,2] [,3]
[1,] NULL NULL NULL
[2,] NULL NULL NULL
[3,] NULL NULL NULL
Pour autant que je sache, la première méthode est plus concise que la dernière. En outre, le premier remplit la matrice avec des NA, tandis que le dernier est rempli de NULL.
Quelle est la "meilleure" façon de faire cela? Dans ce cas, je définis "mieux" comme "meilleures performances", car il s'agit d'un calcul statistique et cette opération aura lieu avec de grands ensembles de données.
Bien que le premier soit plus concis, il n’est pas aussi époustouflant de comprendre, et j’ai l’impression que cela pourrait aller dans un sens ou dans l’autre.
Aussi, quelle est la différence entre NA et NULL dans R? ? NA et? NULL me disent que "NA" a une longueur de "1" alors que NULL a une longueur de "0" - mais y a-t-il plus ici? Ou une meilleure pratique? Cela affectera la méthode que j'utilise pour créer ma matrice.
En cas de doute, testez-vous. La première approche est à la fois plus facile et plus rapide.
> create.matrix <- function(size) {
+ x <- matrix()
+ length(x) <- size^2
+ dim(x) <- c(size,size)
+ x
+ }
>
> system.time(x <- matrix(data=NA,nrow=10000,ncol=10000))
user system elapsed
4.59 0.23 4.84
> system.time(y <- create.matrix(size=10000))
user system elapsed
0.59 0.97 15.81
> identical(x,y)
[1] TRUE
En ce qui concerne la différence entre NA et NULL:
Il y a en fait quatre constantes spéciales.
En outre, il existe quatre constantes spéciales: NULL, NA, Inf et NaN.
NULL est utilisé pour indiquer l'objet vide. NA est utilisé pour les valeurs de données absentes («non disponibles»). Inf désigne l'infini et NaN n'est pas un nombre dans le calcul en virgule flottante IEEE (résultats des opérations respectivement 1/0 et 0/0, par exemple).
Vous pouvez en savoir plus dans le manuel R sur la définition du langage .
Selon cet article nous pouvons faire mieux que préallouer avec NA
en préallouant avec NA_real_
. De l'article:
dès que vous attribuez une valeur numérique à l'une des cellules de 'x', vous devez d'abord forcer la matrice à numérique lorsqu'une nouvelle valeur est attribuée. La matrice logique allouée à l'origine a été allouée en vain et ajoute simplement une empreinte mémoire inutile et un travail supplémentaire pour le ramasse-miettes . Au lieu de l'allouer en utilisant NA_real_ (ou NA_integer_ pour les entiers)
Comme recommandé: testons-le.
testfloat = function(mat){
n=nrow(mat)
for(i in 1:n){
mat[i,] = 1.2
}
}
>system.time(testfloat(matrix(data=NA,nrow=1e4,ncol=1e4)))
user system elapsed
3.08 0.24 3.32
> system.time(testfloat(matrix(data=NA_real_,nrow=1e4,ncol=1e4)))
user system elapsed
2.91 0.23 3.14
Et pour les entiers:
testint = function(mat){
n=nrow(mat)
for(i in 1:n){
mat[i,] = 3
}
}
> system.time(testint(matrix(data=NA,nrow=1e4,ncol=1e4)))
user system elapsed
2.96 0.29 3.31
> system.time(testint(matrix(data=NA_integer_,nrow=1e4,ncol=1e4)))
user system elapsed
2.92 0.35 3.28
La différence est faible dans mes cas de test, mais c'est là.
rows<-3
cols<-3
x<-rep(NA, rows*cols)
x1 <- matrix(x,nrow=rows,ncol=cols)