[Résolu] Création d'une matrice à l'intérieur d'une boucle

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

guillaume souchay
Messages : 9
Enregistré le : 20 Avr 2009, 07:36
Contact :

[Résolu] Création d'une matrice à l'intérieur d'une boucle

Messagepar guillaume souchay » 31 Oct 2011, 21:56

Bonjour,

j'ai cherché sur le forum mais il semble que je n'ai pas trouvé ma réponse. Ma question est assez simple mais j'ai toujours du mal avec les boucles ...

J'étudie de la survie et j'ai une courbe pour une relation entre une survie et un indice de condition corporelle de mes individus (= BCI et j'ai 4405 individus donc 4405 valeurs).
Voici un exemple des données que j'ai :

Code : Tout sélectionner

> test <- cbind(BCI,S_logit,S,phi)
> test[1:10,]
             BCI    S_logit         S       phi
 [1,] -1.1958264 -1.1707333 0.2367225 0.3101394
 [2,] -1.1723595 -1.1317988 0.2438293 0.3224527
 [3,] -1.1408950 -1.0795952 0.2535826 0.3397330
 [4,] -1.1223771 -1.0488717 0.2594418 0.3503328
 [5,] -1.0766264 -0.9729654 0.2742898 0.3779606
 [6,] -1.0378945 -0.9087043 0.2872651 0.4030461
 [7,] -1.0283422 -0.8928558 0.2905208 0.4094847
 [8,] -0.9934615 -0.8349843 0.3025922 0.4338813
 [9,] -0.9845606 -0.8202167 0.3057177 0.4403362
[10,] -0.9825113 -0.8168165 0.3064398 0.4418360


Je voudrais maintenant créer une matrice regroupant la valeur de 2 dérivés partielles pour chaque valeur de BCI
j'ai fait une formule pour calculer chaque dérivée

Code : Tout sélectionner

DerPart_1 <-  phi/(1+phi) - (phi^2)/((1+phi)^2)
DerPart_2 <-  (BCI*phi)/(1+phi) - (BCI*(phi^2))/((1+phi)^2)


Et je souhaiterai accoler ces 2 valeurs dans une matrice 1 ligne 2 col car j'dois ensuite faire du calcul matriciel.
J'ai essayé naivement ceci:

Code : Tout sélectionner

DerPart <- matrix(NA, nrow = 1, ncol = 2)
for (i in 1:4405){
DerPart[i] <- c(DerPart_1[i],DerPart_2[i], nrow=1,ncol=2)
}


Mais bien sur, ca ne fonctionne pas ^^
j'obtiens le message d'erreur suivant:

Code : Tout sélectionner


> for (i in 1:4405){
+ DerPart[i] <- c(DerPart_1[i],DerPart_2[i], nrow=1,ncol=2)
+ }
Il y a eu 50 avis ou plus (utilisez warnings() pour voir les 50 premiers)
> warnings()
Messages d'avis :
1: In DerPart[i] <- c(DerPart_1[i], DerPart_2[i], nrow = 1,  ... :
  le nombre d'objets à remplacer n'est pas multiple de la taille du remplacement
2: In DerPart[i] <- c(DerPart_1[i], DerPart_2[i], nrow = 1,  ... :
  le nombre d'objets à remplacer n'est pas multiple de la taille du remplacement
3: In DerPart[i] <- c(DerPart_1[i], DerPart_2[i], nrow = 1,  ... :


Si vous avez des propositions et des corrections, j'en serai ravi !

Merci bien !

Guillaume
"There is no true model"

Anderson & Burnham 1999

denis laloe
Messages : 119
Enregistré le : 28 Déc 2006, 13:05

Messagepar denis laloe » 01 Nov 2011, 08:56

Bonjour.
Essayez qqc du type :
attach(test)
DerPart_1 <- phi/(1+phi) - (phi^2)/((1+phi)^2)
DerPart_2 <- (BCI*phi)/(1+phi) - (BCI*(phi^2))/((1+phi)^2)


DerPart <- matrix(0, nrow = 4405, ncol = 2)
DerPart[,1]<-DerPart_1
DerPart[,2]<-DerPart_2


la fonction attach(test) relie automatiquement phi à test$phi. DerPArt_1 et Derpart_2 sont des vecteurs.
Vous créez la matrice DerPart en numérique avec les bonnes dimensions

Renaud Lancelot
Messages : 2484
Enregistré le : 16 Déc 2004, 08:01
Contact :

Messagepar Renaud Lancelot » 01 Nov 2011, 09:50

Attention à la fonction attach qui peut aboutit à de sévères déconvenues si on oublie (comme ici) de terminer le travail avec detach. Personnellement, je déconseille vivement son usage. Voir d'ailleurs l'aide ?attach, section "Details".

S'il s'agit de constituer une matrice à deux colonnes à partir de deux vecteurs de même longueur, la solution la plus simple est d'utiliser cbind:

Code : Tout sélectionner

DerPart <- cbind(DerPart_1, DerPart_2)
Renaud

guillaume souchay
Messages : 9
Enregistré le : 20 Avr 2009, 07:36
Contact :

Messagepar guillaume souchay » 01 Nov 2011, 13:04

Merci Renaud pour les conseils sur l'aide de Denis.

S'il s'agit de constituer une matrice à deux colonnes à partir de deux vecteurs de même longueur, la solution la plus simple est d'utiliser cbind:

Code:
DerPart <- cbind(DerPart_1, DerPart_2)

Je souhaite bien faire une matrice de 2 colonnes mais je souhaite qu'elle ne fasse qu'une ligne à chaque fois d'où mon idée d'utiliser une boucle car ensuite je dois faire une multiplication matricielle avec une matrice carré 2*2.
J'ai besoin d'une matrice 1*2 pour chaque valeur de BCI donc je pensais faire la bouche pour avoir autant de matrice que de BCI et faire ainsi mes calculs par la suite.

Voici 3 exemples de ce que j'aimerais faire à l'intérieur de ma boucle:

Code : Tout sélectionner

> DerPart5 <- matrix(c(DerPart_1[5],DerPart_2[5]),nrow=1,ncol=2)
> DerPart5
          [,1]       [,2]
[1,] 0.1990549 -0.2143078
> DT5 <- t(DerPart5)
> DT5
           [,1]
[1,]  0.1990549
[2,] -0.2143078
> DerPart1 <- matrix(c(DerPart_1[1],DerPart_2[1]),nrow=1,ncol=2)
> DT1 <- t(DerPart1)
> DT1
           [,1]
[1,]  0.1806849
[2,] -0.2160678
> DerPart3405 <- matrix(c(DerPart_1[3405],DerPart_2[3405]),nrow=1,ncol=2)
> DT3405 <- t(DerPart3405)
> DerPart3405
          [,1]       [,2]
[1,] 0.2269885 -0.0255558
> DT3405
           [,1]
[1,]  0.2269885
[2,] -0.0255558

En remplaçant les indices par "i"

Si ca peut aider à vous faire comprendre ce que je souhaite
par la suite, je ferai un calcul sur matrice du style

Code : Tout sélectionner

 DerPart[i]%*%E%*%DT[i]


Merci de votre aide !
"There is no true model"



Anderson & Burnham 1999

guillaume souchay
Messages : 9
Enregistré le : 20 Avr 2009, 07:36
Contact :

Messagepar guillaume souchay » 01 Nov 2011, 19:06

bon, après avoir reréfléchi et avoir testé 2-3 choses, j'ai réussi à faire ce que je voulais.

Voici le code finalement utilisé - pour information :

Code : Tout sélectionner

# calcul de la survie sur l'échelle logit
S_logit <- betai + betas*BCI
# on donne un nom à la fonction qui permet de calculer exp(S_logit)
phi <- exp(S_logit)
# calcul de la survie sur l'échelle réelle
S <- phi/(1+phi)
# on va chercher à calculer la variance du paramètre de survie estimé (Y)
# var(Y) = DEDT
# D = vecteur des dérivés partielles de Y selon chaque paramètre Beta
# E = matrice de var-cov associée aux paramètres Beta
# DT = vecteur transposé de D
# comme la matrice n'a que 2 ligne, il faut faire le calcul pour chaque valeur de BCI => boucle
DerPart_1 <-  phi/(1+phi) - (phi^2)/((1+phi)^2)
DerPart_2 <-  (BCI*phi)/(1+phi) - (BCI*(phi^2))/((1+phi)^2)
DerPart <- list()
DT <- list()
variance <- list()
selogit <- list()
sereal <- list()
low95CI <- list()
up95CI<- list()
low95CIreal <- list()
up95CIreal <- list()
# création de la matrice de Var-Cov entre les 2 paramètres B12 et B13 (directement de la sortie Excel du modèle sous E-Surge
E <- matrix(c(0.17553772,0.25710311,0.25710311,0.6516935), nrow = 2)
#écriture de la boucle
for (i in 1:length(DerPart_1)){
DerPart[[i]] <- matrix(c(DerPart_1[i],DerPart_2[i]),nrow=1,ncol=2)
DT[[i]] <- t(DerPart[[i]])
variance[[i]] <- DerPart[[i]]%*%E%*%DT[[i]]     # calcul de la variance var(Y)
selogit[[i]] <- sqrt(variance[[i]])   # calcul de l'erreur standard  sur l'échelle logit
sereal[[i]] <- exp(selogit[[i]])/(1+exp(selogit[[i]]))   #calcul de l'erreur standard sur l'échelle réelle
low95CI[[i]] <- S_logit[i] - 1.96*selogit[[i]]    # calcul de l'intervalle à 95% borne basse  échelle logit
up95CI[[i]] <- S_logit[i] + 1.96*selogit[[i]]     # calcul de l'intervalle à 95% borne haute  échelle logit
low95CIreal[[i]] <- exp(low95CI[[i]])/(1+exp(low95CI[[i]]))    # calcul de l'intervalle à 95% borne basse à l'échelle réelle
up95CIreal[[i]] <- exp(up95CI[[i]])/(1+exp(up95CI[[i]]))       # calcul de l'intervalle à 95% borne haute à l'échelle réelle
}
SElogit <- matrix(unlist(selogit),byrow = T,nrow = 4405, ncol =1)   #crée une matrice des se des beta
SEreal <- matrix(unlist(sereal),byrow = T,nrow = 4405, ncol =1)   #crée une matrice des se des estimées de S
l95CI <- matrix(unlist(low95CI),byrow = T, nrow = 4405, ncol = 1)  #crée une matrice des 95CI lower pour beta
u95CI <- matrix(unlist(up95CI),byrow = T, nrow = 4405, ncol = 1)    #crée une matrice des 95CI upper pour beta
l95CIreal <- matrix(unlist(low95CIreal),byrow = T, nrow = 4405, ncol = 1)  #crée une matrice des 95CI lower pour S
u95CIreal <- matrix(unlist(up95CIreal),byrow = T, nrow = 4405, ncol = 1)    #crée une matrice des 95CI upper pour S
IC <- cbind(BCI,S_logit,l95CI,u95CI,SElogit,S,l95CIreal,u95CIreal,SEreal)  #crée un tableau regroupant la valeur de BCI et les infos sur le beta et la survie
colnames(IC) <- c("bci","beta","B 95% CI lower","B 95% CI upper","se(B)","S","S 95% CI lower","S 95% CI upper","se(S)")
write.table(IC, "IC_bci.txt", sep=" ", col.names = T, row.names = F)


je vais modifier le titre de la question pour mettre en résolu
"There is no true model"



Anderson & Burnham 1999

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 01 Nov 2011, 22:08

Salut,
Je ne suis pas un pro de l'optimisation de code mais :
Je souhaite bien faire une matrice de 2 colonnes mais je souhaite qu'elle ne fasse qu'une ligne à chaque fois d'où mon idée d'utiliser une boucle car ensuite je dois faire une multiplication matricielle avec une matrice carré 2*2.


ça c'est très lourd et inutile.
En restant dans les matrices et les vecteurs, tu peux tout à fait t'en sortir :

Code : Tout sélectionner

> matrix(c(1:10),nc=2)
     [,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8
[4,]    4    9
[5,]    5   10
> mat <- matrix(c(1:10),nc=2)
> matcarre <- matrix(1:4,nc=2)
> apply(mat,1,function(x) x <- x%*%matcarre)
     [,1] [,2] [,3] [,4] [,5]
[1,]   13   16   19   22   25
[2,]   27   34   41   48   55

Ci-dessus, je pars d'une matrice à 2 colonnes (e.g. ton phi et ton BCI..peu importe) et je fais une multiplication matricielle à chaque ligne (ie chaque matrice [1,2]). Je me retrouve avec une matrice dont chaque colonne correspond à une de tes matrices i. Mais c'est bien sûr beaucoup beaucoup plus léger que les listes que tu as mis en place.

Nicolas


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité