variance sur liste

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

Golfesh Alphonse
Messages : 138
Enregistré le : 30 Aoû 2012, 08:57

variance sur liste

Messagepar Golfesh Alphonse » 28 Juil 2015, 13:48

Bonjour!

Je voudrais calculer la variance de ma liste:

Code : Tout sélectionner

ocP <- structure(list(z = structure(c(2L, 1L, 1L), .Dim = 3L, .Dimnames = structure(list(
    c("9", "5", "8")), .Names = "")), a = structure(c(2L, 1L,
1L), .Dim = 3L, .Dimnames = structure(list(c("5", "7", "10")), .Names = "")),
    b = structure(c(2L, 2L, 1L, 1L, 1L, 1L), .Dim = 6L, .Dimnames = structure(list(
        c("4", "5", "3", "7", "8", "10")), .Names = "")), c = structure(c(3L,
    3L, 1L, 1L, 1L), .Dim = 5L, .Dimnames = structure(list(c("2",
    "3", "1", "4", "5")), .Names = "")), d = structure(c(2L,
    1L, 1L, 1L), .Dim = 4L, .Dimnames = structure(list(c("4",
    "3", "5", "6")), .Names = "")), e = structure(c(1L, 1L), .Dim = 2L, .Dimnames = structure(list(
        c("6", "8")), .Names = "")), `s` = structure(1L, .Names = "3")), .Names = c("z",
"a", "b", "c", "d", "e", "s"))



ce code ne marche pas du tout, j'obtiens des valeurs négatives:

Code : Tout sélectionner

mapply(function(x){
a<- matrix(0,length(ocP[[x]]),2)
a[,1] <- as.numeric(names(ocP[[x]]))
a[,2] <- as.numeric(as.vector(ocP[[x]]))
return(var(a))
},names(ocP),SIMPLIFY =FALSE)



et avec celui des valeurs fausses:

Code : Tout sélectionner

mapply(function(x){
var(ocP[[x]])
},names(ocP),SIMPLIFY =FALSE)

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

Re: variance sur liste

Messagepar Nicolas Péru » 28 Juil 2015, 14:35

Bonjour,

Si tu veux qu'on te réponde il faut que tu nous dises c que tu veux faire exactement car les codes que tu donnes et que tu dis être faux font 2 choses différentes.

Nicolas

Golfesh Alphonse
Messages : 138
Enregistré le : 30 Aoû 2012, 08:57

Re: variance sur liste

Messagepar Golfesh Alphonse » 28 Juil 2015, 14:52

Par exemple, l'élément de ma liste nommé $z

$z

9 5 8
2 1 1


le 9 a une occurrence de 2
le 5 une occurrence de 1
le 8 une occurrence de 1

J'ai pu calculer la moyenne qui de 7.75

Je voudrais trouver la variance

Navarre Julien
Messages : 367
Enregistré le : 20 Avr 2012, 08:27

Re: variance sur liste

Messagepar Navarre Julien » 28 Juil 2015, 15:13

Bonjour,

le format de tes données n'est vraiment pas adapté pour utiliser la fonction "var", si toutefois tu insistes :

var prends comme mean, un vecteur comme argument ex pour ton premier élément : var(c(9, 9, 5, 8))

Tu peux reproduire ce vecteur pour chacun de tes éléments en vectorisant la fonction rep. On crée un vecteur dans lequel on a répété chaque valeur autant de fois que son occurrence.

Code : Tout sélectionner

lapply(ocP, function(x) var(unlist(mapply(rep, names(x), x))))


Bref, une très mauvaise idée.

edit : Au temps pour moi la fonction rep est déjà vectorisée, pas besoin du mapply.

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: variance sur liste

Messagepar Gabriel Terraz » 28 Juil 2015, 15:15

Salut,

Tu peux faire comme cela :

Code : Tout sélectionner

lapply(ocP, function(x) var(as.numeric(rep(names(x) , x))))

Eric Casellas
Messages : 767
Enregistré le : 06 Jan 2009, 14:59

Re: variance sur liste

Messagepar Eric Casellas » 28 Juil 2015, 15:19

Bonjour,

Dans la mesure ou les noms de colonnes sont bien des nombres ceci devrait permettre de calculer les moyennes et variances :

Code : Tout sélectionner

(means <- sapply(ocP, function(X) { sum(as.numeric(names(X))*X)/sum(X)}))

(vars <- sapply(1:length(means), function(i) { sum(((as.numeric(names(ocP[[i]]))-means[i])*ocP[[i]])^2)/sum(ocP[[i]])}))
Eric

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

Re: variance sur liste

Messagepar Nicolas Péru » 28 Juil 2015, 15:30

Tes données semblent être le résultat d'un table() par groupe. Tu n'as pas la donnée de base pour que tu puisses calculer ta variance par groupe directement ??

Nicolas

Golfesh Alphonse
Messages : 138
Enregistré le : 30 Aoû 2012, 08:57

Re: variance sur liste

Messagepar Golfesh Alphonse » 28 Juil 2015, 15:43

Merci beaucoup pour votre aide vos code marchent très bien.... mais... dans l'exemple
$z
9 5 8
2 1 1


r retourne 3.58333

et quand je calcule à la main et sur des sites en ligne je trouve 2.68.... Pourquoi?

Dans quel dossier puis-je relire le codage de la fonction var et le modifier si j'ai besoin?

Golfesh Alphonse
Messages : 138
Enregistré le : 30 Aoû 2012, 08:57

Re: variance sur liste

Messagepar Golfesh Alphonse » 28 Juil 2015, 18:51

Dans le doute, j'ai recodé une fonction. Qu'en pensez vous?

Code : Tout sélectionner

variance <- function(vecteur){
oc <- table(vecteur)
pdt <-  mapply( function(x) {as.numeric(names(oc[x]))*as.numeric(oc[x])  },names(oc),SIMPLIFY =FALSE)
moyenne <- sum(unlist(pdt))/length(vecteur)
elemNum <- mapply( function(x) {
 as.numeric(oc[x])*((as.numeric(names(oc[x]))-moyenne)*(as.numeric(names(oc[x]))-moyenne))
},names(oc),SIMPLIFY =FALSE)
return(sum(unlist(elemNum))/sum(unlist(oc)))
}


J'aimerai quand même savoir dans quel dossier de r lire le code de var()...

Bastien Gamboa
Messages : 151
Enregistré le : 13 Jan 2011, 21:31

Re: variance sur liste

Messagepar Bastien Gamboa » 29 Juil 2015, 06:55

Bonjour,

La fonction var() donne une estimation non-biaisée de la variance, donc avec le dénominateur n-1 et non n (voir ?var).

Pour le vérifier :

Code : Tout sélectionner

((9-7.75)^2 + (9-7.75)^2 + (8-7.75)^2 + (5-7.75)^2)/4 # 2.6875
((9-7.75)^2 + (9-7.75)^2 + (8-7.75)^2 + (5-7.75)^2)/3 # 3.58333

Ta fonction perso prend en argument 'vecteur', ainsi il ne sert à rien de passer par table() pour compter les occurences de chaque valeurs et ensuite reproduire 'vecteur' à partir des résultats du table(). Un var(vecteur) te donneras l'estimation non-biaisée de la variance qu'il te faut.

Pour accéder au code de la fonction var(), tapes tout simplement var sans les parenthèses dans R et entrée et tu verras le code R.

HTH
Bastien

Golfesh Alphonse
Messages : 138
Enregistré le : 30 Aoû 2012, 08:57

Re: variance sur liste

Messagepar Golfesh Alphonse » 29 Juil 2015, 08:11

Merci!

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

Re: variance sur liste

Messagepar Nicolas Péru » 29 Juil 2015, 08:28

J'enfonce le clou posé par Bastien.

Ton code me semble inutile. Je l'ai suggéré dans un précédent message sans avoir vu le code de ta fonction. Ce dernier confirme ce que je pensais, et comme le souligne Bastien, tu fais un table d'un vecteur pour revenir au vecteur initial. Quel intérêt ?

Pourquoi n'applique tu pas un calcul de variance pour chacun de tes groupes ?

Pour ce qui est du code de var, il est en C. Il faut donc charger les sources du package {stats}

Golfesh Alphonse
Messages : 138
Enregistré le : 30 Aoû 2012, 08:57

Re: variance sur liste

Messagepar Golfesh Alphonse » 29 Juil 2015, 08:40

Quel intérêt ?


J'ai voulu me faciliter le travail en isolant les éléments du calcul a faire. Je vois pas ou je reviens au vecteur après être passé par table. Pouvez vous me l'indiquer?

Pourquoi n'applique tu pas un calcul de variance pour chacun de tes groupes ?

Je vais le faire aussi au final. Je ne comprenais pas pourquoi var() ne donnait pas les même résultat que ceux attendus. Dans mon cas je ne sais pas si la variance biaisée donnée par r sera plus appropriée que la variance simple. Je vais tester les deux.

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

Re: variance sur liste

Messagepar Nicolas Péru » 29 Juil 2015, 11:27

Dans un premier temps, je te propose une simplification en termes de code car les mapply que tu emploies sont lourds et inutile étant donné la nature vectorisée des calculs que tu veux faire.

Code : Tout sélectionner

vecteur <- c(5,3,3,6,9,7,5,8,4,1,2,8,2,5,8,5)
oc <- table(vecteur)


Pour la création de pdt, ceci:

Code : Tout sélectionner

unlist(mapply( function(x) {as.numeric(names(oc[x]))*as.numeric(oc[x])  },names(oc),SIMPLIFY =FALSE))
 1  2  3  4  5  6  7  8  9
 1  4  6  4 20  6  7 24  9

Donne le même résultat que:

Code : Tout sélectionner

as.numeric(names(oc))*oc
vecteur
 1  2  3  4  5  6  7  8  9
 1  4  6  4 20  6  7 24  9

Donc je te suggère de garder cette dernière solution qui est certainement plus lisible et plus rapide.

Code : Tout sélectionner

pdt <- as.numeric(names(oc))*oc
moyenne <- sum(pdt)/length(vecteur)

Ensuite, ceci:

Code : Tout sélectionner

unlist(mapply( function(x) {
 as.numeric(oc[x])*((as.numeric(names(oc[x]))-moyenne)*(as.numeric(names(oc[x]))-moyenne))
},names(oc),SIMPLIFY =FALSE))
est équivalent à

Code : Tout sélectionner

pdt-(oc*moyenne))*(pdt-(oc*moyenne))

Donc, on garde cette solution. et ta fonction devient :

Code : Tout sélectionner

variance <- function(vecteur){
oc <- table(vecteur)
pdt <- as.numeric(names(oc))*oc
moyenne <- sum(pdt)/length(vecteur)
elemNum <- pdt-(oc*moyenne))*(pdt-(oc*moyenne))
return(sum(elemNum)/sum(oc))#tu ajoutes un "-1" au dénominateur si tu veux l'estimateur non biaisé.
}


On en vient à l'intérêt de ta fonction
oc est un objet qui te dit le nombre de fois où chaque valeur est répétée : les "names" de oc sont les valeurs trouvées et les valeurs dans oc sont les nombres de répétition.
Donc quand tu fais

Code : Tout sélectionner

mapply( function(x) {as.numeric(names(oc[x]))*as.numeric(oc[x])  },names(oc),SIMPLIFY =FALSE)

tu lui dis de transformer un des names de oc en nombre, c'est à dire que tu retrouve les valeurs numérique trouvée dans vecteur que tu viens multiplier par le nombre de fois où elle a été trouvée...ça revient exactement à prendre le vecteur initial et faire la somme des valeurs identiques

Code : Tout sélectionner

sort(vecteur) #le vecteur ordonné
[1] 1 2 2 3 3 4 5 5 5 5 6 7 8 8 8 9
[1]  1  4  6  4 20  6  7 24  9 #le vecteur modifié en faisant la somme des valeurs répétées


Donc si en travaillant sur oc, tu ne fais qu'utiliser vecteur de façon détournée (= tu te compliques sérieusement la vie), alors ta fonction reviens exactement à calculer la variance de ton vecteur (au correctif de biais près). Si tu as des morceaux de vecteurs, on peut voir ça comme un grand vecteur initial découpé en groupe selon un facteur de regroupement, d'où ma suggestion de faire un calcul de variance par groupe. Par ex. :

Code : Tout sélectionner

tapply(vecteur,groupe,var)


il reste possible que je n'ai pas compris une subtilité de ta demande :)

Nicolas

Golfesh Alphonse
Messages : 138
Enregistré le : 30 Aoû 2012, 08:57

Re: variance sur liste

Messagepar Golfesh Alphonse » 31 Juil 2015, 17:55

Merci pour cette excellente explication Nicolas!


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité