Bonjour :
Ma question porte sur la manière d'extraire des données d'une matrice de nombres A(n,p) à partir d'un vecteur y(n) qui donne pour chaque ligne de la matrice la colonne où aller chercher l'élément.
Le traitement est facile en notation indicielle : for (k in 1:n) {z[k] = A[k, y[k]]}
Comme j'ai des matrices avec beaucoup de lignes et que le traitement doit être répété dans un Monte-Carlo, je me suis dit qu'avec des instructions vectorielles je devrais obtenir de meilleures performances qu'en mode indiciel mais ça n'est pas le cas (cf ci dessous).
Cela dit, je ne maitrise pas bien le langage R et je pense que mes expressions en notation vectorielle sont peu performantes...
Solution 1 : z <- rep(0,n); for (i in 1:p) { z= ifelse(y==i, A[, i],z) }
Solution 2 : z <- diag(A[,y])
Pourtant, je pense qu'il doit bien y avoir des instructions vectorielles simples dans R qui permettent d'obtenir directement z avec de meilleures performances que le 'traitement indiciel' ?
Peut être avec la fonction subset ? Mais je ne maitrise pas assez bien le langage pour écrire la bonne instruction.
Merci d'avance pour vos propositions à ce sujet...
EXEMPLE POUR ILLUSTRER LE SUJET (sur la base de 100.000 itérations)
> n = 500; p =10
> A <- matrix(data=runif(n*p),nrow=n, ncol=p, byrow=TRUE) # génération de la matrice A(500,10) avec des valeurs aléatoires
> y <- round((p-1)*runif(n)+1) # génération du vecteur y(500) avec la position de la valeur de A à prendre sur les colonnes
> z <- rep(0,n)
>
> tt <- Sys.time()
> for (iter in 1:1e5) {for (k in 1:n) {z[k] = A[k, y[k]]}}
> elapse <- difftime(Sys.time(),tt, units = "secs")
> print (elapse)
Time difference of 87.90625 secs
>
> tt <- Sys.time()
> for (iter in 1:1e5) {for (i in 1:p) {z= ifelse(y==i, A[, i],z) } }
> elapse <- difftime(Sys.time(),tt, units = "secs")
> print(elapse)
Time difference of 105.1406 secs[/b]
>
> tt <- Sys.time()
> for (iter in 1:1e5) {z <- diag(A[,y])}
> elapse <- difftime(Sys.time(),tt, units = "secs")
> print (elapse)
Time difference of 755.6719 secs