modif chdtxt, a tester, problemes sur double sur rst
[iramuteq] / Rscripts / chdtxt.R
1 #Author: Pierre Ratinaud
2 #Copyright (c) 2008-2009 Pierre Ratinaud
3 #Lisense: GNU/GPL
4
5
6 #fonction pour la double classification
7 #cette fonction doit etre splitter en 4 ou 5 fonctions
8
9 AssignClasseToUce <- function(listuce, chd) {
10     print('assigne classe -> uce')
11     chd[listuce[,2]+1,]
12 }
13
14 fille<-function(classe,classeuce) {
15         listfm<-unique(unlist(classeuce[classeuce[,classe%/%2]==classe,]))
16         listf<-listfm[listfm>=classe]
17         listf<-unique(listf)
18         listf
19 }
20
21
22 croiseeff <- function(croise, classeuce1, classeuce2) {
23     cl1 <- 0
24     cl2 <- 1
25     for (i in 1:ncol(classeuce1)) {
26         cl1 <- cl1 + 2
27         cl2 <- cl2 + 2
28         clj1 <- 0
29         clj2 <- 1
30         for (j in 1:ncol(classeuce2)) {
31             clj1 <- clj1 + 2
32             clj2 <- clj2 + 2
33             croise[cl1 - 1, clj1 -1] <- length(which(classeuce1[,i] == cl1 & classeuce2[,j] == clj1))
34             croise[cl1 - 1, clj2 -1] <- length(which(classeuce1[,i] == cl1 & classeuce2[,j] == clj2))
35             croise[cl2 - 1, clj1 -1] <- length(which(classeuce1[,i] == cl2 & classeuce2[,j] == clj1))
36             croise[cl2 - 1, clj2 -1] <- length(which(classeuce1[,i] == cl2 & classeuce2[,j] == clj2))
37         }
38     }
39     croise
40 }
41
42 addallfille <- function(lf) {
43     nlf <- list()
44     for (i in 1:length(lf)) {
45         if (! is.null(lf[[i]])) {
46             nlf[[i]] <- lf[[i]]
47             filles <- lf[[i]]
48             f1 <- filles[1]
49             f2 <- filles[2]
50             if (f1 > length(lf)) {
51                 for (j in (length(lf) + 1):f2) {
52                     nlf[[j]] <- 0
53                 }
54             }
55         } else {
56             nlf[[i]] <- 0
57         }
58     }
59 nlf
60 }
61
62 getfille <- function(nlf, classe, pf) {
63     if (length(nlf[[classe]]) == 1) {
64         return(pf)
65     } else {
66         pf <- c(pf, nlf[[classe]])
67         c1 <- nlf[[classe]][1]
68         c2 <- nlf[[classe]][2]
69         pf <- getfille(nlf, c1, pf)
70         pf <- getfille(nlf, c2, pf)
71     }
72     return(pf)
73 }
74
75 getmere <- function(list_mere, classe) {
76     i <- classe
77     pf <- NULL
78     while (i != 1 ) {
79         pf <- c(pf, list_mere[[i]])
80         i <- list_mere[[i]]
81     }
82     pf
83 }
84
85 getfillemere <- function(list_fille, list_mere, classe) {
86     return(c(getfille(list_fille, classe, NULL), getmere(list_mere, classe)))
87 }
88
89 #nbt nbcl = nbt+1 tcl=((nbt+1) *2) - 2  n1[,ncol(n1)], nchd1[,ncol(nchd1)]
90 Rchdtxt<-function(uceout, chd1, chd2 = NULL, mincl=0, classif_mode=0, nbt = 9) {
91         #FIXME: le nombre de classe peut etre inferieur
92     nbcl <- nbt + 1
93     tcl <- ((nbt+1) * 2) - 2
94     #Assignation des classes
95         classeuce1<-AssignClasseToUce(listuce1,chd1$n1)
96         if (classif_mode==0) {
97                 classeuce2<-AssignClasseToUce(listuce2,chd2$n1)
98     } else {
99                 classeuce2<-classeuce1
100     }
101
102         #calcul des poids (effectifs)
103
104     makepoids <- function(classeuce, poids) {
105         cl1 <- 0
106         cl2 <- 1
107         for (i in 1:nbt) {
108             cl1 <- cl1 + 2
109             cl2 <- cl2 + 2
110             poids[cl1 - 1] <- length(which(classeuce[,i] == cl1))
111             poids[cl2 - 1] <- length(which(classeuce[,i] == cl2))
112         }
113         poids
114     }
115
116 #       makepoids<-function(classeuce,poids) {
117 #           for (classes in 2:(tcl + 1)){
118 #                   for (i in 1:ncol(classeuce)) {
119 #                       if (poids[(classes-1)]<length(classeuce[,i][classeuce[,i]==classes])) {
120 #                           poids[(classes-1)]<-length(classeuce[,i][classeuce[,i]==classes])
121 #                       }
122 #                   }
123 #           }
124 #           poids
125 #       }
126     print('make poids')
127         poids1<-vector(mode='integer',length = tcl)
128         poids1<-makepoids(classeuce1,poids1)
129         if (classif_mode==0) {
130                 poids2<-vector(mode='integer',length = tcl)
131                 poids2<-makepoids(classeuce2,poids2)
132         } else {
133                 poids2<-poids1
134         }
135     
136     print('croisement classif')
137
138 #    croise=matrix(ncol=tcl,nrow=tcl)
139 #
140 #    docroise <- function(croise, classeuce1, classeuce2) {
141 #       #production du tableau de contingence
142 #       for (i in 1:ncol(classeuce1)) {
143 #           #poids[i]<-length(classeuce1[,i][x==classes])
144 #           for (j in 1:ncol(classeuce2)) {
145 #                   tablecroise<-table(classeuce1[,i],classeuce2[,j])
146 #                   tabcolnames<-as.numeric(colnames(tablecroise))
147 #                   #tabcolnames<-c(tabcolnames[(length(tabcolnames)-1)],tabcolnames[length(tabcolnames)])
148 #                   tabrownames<-as.numeric(rownames(tablecroise))
149 #                   #tabrownames<-c(tabrownames[(length(tabrownames)-1)],tabrownames[length(tabrownames)])
150 #                   for (k in (ncol(tablecroise)-1):ncol(tablecroise)) {
151 #                       for (l in (nrow(tablecroise)-1):nrow(tablecroise)) {
152 #                           croise[(tabrownames[l]-1),(tabcolnames[k]-1)]<-tablecroise[l,k]
153 #                       }
154 #                   }
155 #           }
156 #       }
157 #        croise
158 #    }
159     croise <- croiseeff( matrix(ncol=tcl,nrow=tcl), classeuce1, classeuce2)
160     if (classif_mode == 0) {ind <- (nbcl * 2)} else {ind <- nbcl}
161         if (mincl==0){
162                 mincl<-round(nrow(classeuce1)/ind)
163         }
164         if (mincl<3){
165                 mincl<-3
166         }
167     print(mincl)        
168         #print('table1')
169         #print(croise)
170         #tableau des chi2 signes
171     print('croise chi2')
172         #chicroise<-croise
173
174 #    nr <- nrow(classeuce1)
175 #    newchicroise <- function(croise, mincl, nr, poids1, poids2) {
176 #        chicroise <- croise
177 #        chicroise[which(croise < mincl)] <- 0
178 #        tocompute <- which(chicroise > 0, arr.ind = TRUE)
179 #        for (i in 1:nrow(tocompute)) {
180 #            chitable <- matrix(ncol=2,nrow=2)
181 #            chitable[1,1] <- croise[tocompute[i,1],  tocompute[i,2]]
182 #            chitable[1,2] <- poids1[tocompute[i,1]] - chitable[1,1]
183 #            chitable[2,1] <- poids2[tocompute[i,2]] - chitable[1,1]
184 #            chitable[2,2] <- nr - poids2[tocompute[i,2]] - chitable[1,2]
185 #            chitest<-chisq.test(chitable,correct=FALSE)
186 #            chicroise[tocompute[i,1],  tocompute[i,2]] <- ifelse(chitable[1,1] > chitest$expected[1,1], round(chitest$statistic,digits=7), -round(chitest$statistic,digits=7))
187 #        }
188 #        chicroise
189 #    }
190 #
191         
192
193         dochicroise <- function(croise, mincl) {
194         chicroise <- croise
195         for (i in 1:nrow(croise)) {
196                 for (j in 1:ncol(croise)) {
197                     if (croise[i,j]==0) {
198                         chicroise[i,j]<-0
199                     } else if (croise[i,j]<mincl) { 
200                         chicroise[i,j]<-0
201                     } else {
202                         chitable<-matrix(ncol=2,nrow=2)
203                         chitable[1,1]<-croise[i,j]
204                         chitable[1,2]<-poids1[i]-chitable[1,1]
205                         chitable[2,1]<-poids2[j]-chitable[1,1]
206                         chitable[2,2]<-nrow(classeuce1)-poids2[j]-chitable[1,2]
207                         chitest<-chisq.test(chitable,correct=FALSE)
208                         if ((chitable[1,1]-chitest$expected[1,1])<0) {
209                             chicroise[i,j]<--round(chitest$statistic,digits=7)
210                         } else {
211                             chicroise[i,j]<-round(chitest$statistic,digits=7)
212                 #print(chitest)
213                         }
214                     }
215                 }   
216             }
217         chicroise
218     }
219     chicroise <- dochicroise(croise, mincl)
220     print('fin croise')
221         #print(chicroise)
222         #determination des chi2 les plus fort
223         chicroiseori<-chicroise
224
225     doxy <- function(chicroise) {
226         listx <- NULL
227         listy <- NULL
228         listxy <- which(chicroise > 3.84, arr.ind = TRUE)
229         #print(listxy)
230         val <- chicroise[which(chicroise > 3.84)]
231         ord <- order(val, decreasing = TRUE)
232         listxy <- listxy[ord,]
233         #for (i in 1:nrow(listxy)) {
234         #    if ((!listxy[,2][i] %in% listx) & (!listxy[,1][i] %in% listy)) {
235         #        listx <- c(listx, listxy[,2][i])
236         #        listy <- c(listy, listxy[,1][i])
237         #    }
238         #}
239         xy <- list(x = listxy[,2], y = listxy[,1])
240         xy
241     }
242     xy <- doxy(chicroise)
243     print(xy)
244     listx <- xy$x
245     listy <- xy$y
246
247 #       maxi<-vector()
248 #       chimax<-vector()
249 #       for (i in 1:tcl) {
250 #           maxi[i]<-which.max(chicroise)
251 #           chimax[i]<-chicroise[maxi[i]]
252 #           chicroise[maxi[i]]<-0
253 #       }
254 #       testpres<-function(x,listcoord) {
255 #           for (i in 1:length(listcoord)) {
256 #                   if (x==listcoord[i]) {
257 #                       return(-1)
258 #                   } else {
259 #                       a<-1
260 #                   }
261 #           }
262 #           a
263 #       }
264 #       c.len=nrow(chicroise)
265 #       r.len=ncol(chicroise)
266 #       listx<-c(0)
267 #       listy<-c(0)
268 #       rang<-0
269 #       cons<-list()
270 #       #on garde une valeur par ligne / colonne
271 #       for (i in 1:length(maxi)) {
272 #       #coordonnées de chi2 max
273 #        #coord <- arrayInd(maxi[i], dim(chicroise))
274 #        #x.co <- coord[1,2]
275 #        #y.co <- coord[1,1]
276 #           x.co<-ceiling(maxi[i]/c.len)
277 #           y.co<-maxi[i]-(x.co-1)*c.len
278 #        #print(x.co)
279 #        #print(y.co)
280 #        #print(arrayInd(maxi[i], dim(chicroise)))
281 #           a<-testpres(x.co,listx)
282 #           b<-testpres(y.co,listy)
283 #           
284 #           if (a==1) {
285 #                       if (b==1) {
286 #                           rang<-rang+1
287 #                           listx[rang]<-x.co
288 #                           listy[rang]<-y.co
289 #                       }
290 #           }
291 #           cons[[1]]<-listx
292 #           cons[[2]]<-listy
293 #       }
294         #pour ecrire les resultats
295         for (i in 1:length(listx)) {
296             txt<-paste(listx[i]+1,listy[i]+1,sep=' ')
297             txt<-paste(txt,croise[listy[i],listx[i]],sep=' ')
298             txt<-paste(txt,chicroiseori[listy[i],listx[i]],sep=' ')
299             print(txt)
300         }
301
302         #colonne de la classe
303         #trouver les filles et les meres 
304         trouvefillemere<-function(classe,chd) {
305             unique(unlist(chd[chd[,classe%/%2]==classe,]))
306         }
307
308
309 #----------------------------------------------------------------------
310     findbestcoord <- function(classeuce1, classeuce2) {
311         #fillemere1 <- NULL
312         #fillemere2 <- NULL
313
314         #fillemere1 <- unique(classeuce1)
315         #if (classif_mode == 0) {
316         #    fillemere2 <- unique(classeuce2)
317         #} else {
318         #    fillemere2 <- fillemere1
319         #}
320
321         #
322         listcoordok <- list()
323         maxcl <- 0
324         nb <- 0
325         lf1 <- addallfille(chd1$list_fille) 
326         if (classif_mode == 0) {
327             lf2 <- addallfille(chd2$list_fille)
328         } else {
329             lf2 <- lf1
330         }
331         lme1 <- chd1$list_mere
332         if (classif_mode == 0) {
333             lme2 <- chd2$list_mere
334         } else {
335             lme2 <- lme1
336         }
337         for (first in 1:length(listx)) {
338             coordok <- NULL
339             f1 <- NULL
340             f2 <- NULL
341             listxp<-listx
342             listyp<-listy
343             
344             #listxp<-listx[first:length(listx)]
345             #listxp<-c(listxp,listx[1:(first-1)])
346             #listyp<-listy[first:length(listy)]
347             #listyp<-c(listyp,listy[1:(first-1)])
348             listxp <- listxp[order(listx, decreasing = TRUE)]
349             listyp <- listyp[order(listx, decreasing = TRUE)]
350             #listxp<-c(listxp[first:length(listx)], listx[1:(first-1)])
351             #listyp<-c(listyp[first:length(listy)], listy[1:(first-1)])
352             for (i in 1:length(listx)) {
353                 if( (!(listxp[i]+1) %in% f1) & (!(listyp[i]+1) %in% f2) ) {
354                     #print(listyp[i]+1)
355                     #print('not in')
356                     #print(f2)
357                     coordok <- rbind(coordok, c(listyp[i] + 1,listxp[i] + 1))
358                     #print(c(listyp[i] + 1,listxp[i] + 1))
359                     un1 <- getfillemere(lf2, chd2$list_mere, listxp[i] + 1)
360                     f1 <- c(f1, un1)
361                     f1 <- c(f1, listxp[i] + 1)
362                     un2 <- getfillemere(lf1, chd1$list_mere, listyp[i] + 1)
363                     f2 <- c(f2, un2)
364                     f2 <- c(f2, listyp[i] + 1)
365                 }
366                 #print(coordok)
367             }
368             #if (nrow(coordok) > maxcl) {
369                 nb <- 1
370             #    listcoordok <- list()
371                 listcoordok[[nb]] <- coordok
372             #    maxcl <- nrow(coordok)
373             #} else if (nrow(coordok) == maxcl) {
374                 nb <- nb + 1
375             #    listcoordok[[nb]] <- coordok
376             #}
377         }
378         listcoordok <- unique(listcoordok)
379         print(listcoordok)
380         best <- 1
381         if (length(listcoordok) > 1) {
382             maxchi <- 0
383             for (i in 1:length(listcoordok)) {
384                 chi <- NULL
385                 uce <- NULL
386                 for (j in 1:nrow(listcoordok[[i]])) {
387                     chi<-c(chi,croise[(listcoordok[[i]][j,1]-1),(listcoordok[[i]][j,2]-1)])
388                     uce<-c(uce,chicroiseori[(listcoordok[[i]][j,1]-1),(listcoordok[[i]][j,2]-1)])
389                 }
390                 if (maxchi < sum(chi)) {
391                     maxchi <- sum(chi)
392                     suce <- sum(uce)
393                     best <- i
394                 }
395             }
396         print(suce/nrow(classeuce1))
397         }
398         listcoordok[[best]]
399     }
400 #---------------------------------------------------------------------------------   
401         #pour trouver une valeur dans une liste
402         #is.element(elem, list)
403         #== elem%in%list
404     oldfindbestcoord <- function(listx, listy) {
405         coordok<-NULL
406         trouvecoordok<-function(first) {
407             fillemere1<-NULL
408             fillemere2<-NULL
409             listxp<-listx
410             listyp<-listy
411             listxp<-listx[first:length(listx)]
412             listxp<-c(listxp,listx[1:(first-1)])
413             listyp<-listy[first:length(listy)]
414             listyp<-c(listyp,listy[1:(first-1)])
415             for (i in 1:length(listxp)) {
416                 if (!(listxp[i]+1)%in%fillemere1) {
417                         if (!(listyp[i]+1)%in%fillemere2) {
418                             coordok<-rbind(coordok,c(listyp[i]+1,listxp[i]+1))
419                             fillemere1<-c(fillemere1,trouvefillemere(listxp[i]+1,chd2$n1))
420                             fillemere2<-c(fillemere2,trouvefillemere(listyp[i]+1,chd1$n1))
421                         }
422                }
423             }
424             coordok
425         }
426     #fonction pour trouver le nombre maximum de classes
427         findmaxclasse<-function(listx,listy) {
428             listcoordok<-list()
429             maxcl<-0
430             nb<-1
431             for (i in 1:length(listy)) {
432                         coordok<-trouvecoordok(i)
433                         if (maxcl <= nrow(coordok)) {
434                             maxcl<-nrow(coordok)
435                             listcoordok[[nb]]<-coordok
436                             nb<-nb+1
437                         }
438             }
439             listcoordok<-unique(listcoordok)
440             print(listcoordok)
441                 #si plusieurs ensemble avec le meme nombre de classe, on conserve
442                 #la liste avec le plus fort chi2
443             if (length(listcoordok)>1) {
444                     maxchi<-0
445                     best<-NULL
446                     for (i in 1:length(listcoordok)) {
447                         chi<-NULL
448                         uce<-NULL
449                         if (nrow(listcoordok[[i]])==maxcl) {
450                             for (j in 1:nrow(listcoordok[[i]])) {
451                                 chi<-c(chi,croise[(listcoordok[[i]][j,1]-1),(listcoordok[[i]][j,2]-1)])
452                                 uce<-c(uce,chicroiseori[(listcoordok[[i]][j,1]-1),(listcoordok[[i]][j,2]-1)])
453                             }
454                             if (maxchi < sum(chi)) {
455                                 maxchi <- sum(chi)
456                                 suce <- sum(uce)
457                                 best <- i
458                             } 
459                         }
460                     }
461             }
462             print((maxchi/nrow(classeuce1)*100))
463             listcoordok[[best]]
464         }
465         print('cherche max')
466             coordok<-findmaxclasse(listx,listy)
467             coordok
468     }
469         #findmaxclasse(listx,listy)
470         #coordok<-trouvecoordok(1)
471     #coordok <- oldfindbestcoord(listx, listy)
472     coordok <- findbestcoord(listx, listy)
473
474
475         lfilletot<-function(classeuce,x) {
476             listfille<-NULL
477             for (classe in 1:nrow(coordok)) {
478                         listfille<-unique(c(listfille,fille(coordok[classe,x],classeuce)))
479                         listfille
480             }
481         }
482     print('listfille')
483         listfille1<-lfilletot(classeuce1,1)
484         listfille2<-lfilletot(classeuce2,2)
485
486         #utiliser rownames comme coordonnees dans un tableau de 0
487         Assignclasse<-function(classeuce,x) {
488             nchd<-matrix(0,ncol=ncol(classeuce),nrow=nrow(classeuce))
489             for (classe in 1:nrow(coordok)) {
490                         clnb<-coordok[classe,x]
491                         colnb<-clnb%/%2
492             nchd[which(classeuce[,colnb]==clnb), colnb:ncol(nchd)] <- classe
493             }
494             nchd
495         }
496         print('commence assigne new classe')
497         nchd1<-Assignclasse(classeuce1,1)
498         if (classif_mode==0) {
499                 nchd2<-Assignclasse(classeuce2,2)
500         } else {
501                 nchd2<-nchd1
502     }
503         print('fini assign new classe')
504         #croisep<-matrix(ncol=nrow(coordok),nrow=nrow(coordok))
505     nchd2[which(nchd1[,ncol(nchd1)]==0),] <- 0
506     nchd2[which(nchd1[,ncol(nchd1)]!=nchd2[,ncol(nchd2)]),] <- 0
507     nchd1[which(nchd2[,ncol(nchd2)]==0),] <- 0
508
509         print('fini croise')
510         elim<-which(nchd1[,ncol(nchd1)]==0)
511         keep<-which(nchd1[,ncol(nchd1)]!=0)
512         n1<-nchd1[nchd1[,ncol(nchd1)]!=0,]
513         n2<-nchd2[nchd2[,ncol(nchd2)]!=0,]
514         #clnb<-nrow(coordok)
515         print('fini')
516         write.csv2(nchd1[,ncol(nchd1)],uceout)
517         res <- list(n1 = nchd1, coord_ok = coordok, cuce1 = classeuce1, cuce2 = classeuce2)
518         res
519 }