problème calcul médiane pondérée

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

Antoine Kimmoun
Messages : 2
Enregistré le : 06 Fév 2019, 15:20

problème calcul médiane pondérée

Messagepar Antoine Kimmoun » 07 Fév 2019, 09:45

Bonjour,

Je débute en R... et je bloque sur quelque chose de tout bête...

Voici une partie de mon jeu de donnée

Code : Tout sélectionner

 Mp
     median_age_1 median_age_2 median_age_3 median_age_4 number_1 number_2 number_3 number_4
1              NA           NA           NA           NA     1055      324       NA       NA
2              NA           NA           NA           NA      171      170      169       NA
3              NA           NA           NA           NA      235       46       79      113
4              NA           NA           NA           NA      481      810       NA       NA
5              NA           NA           NA           NA      834      371       NA       NA
6              NA           NA           NA           NA       92       69       NA       NA
7            83.0         86.0           NA           NA      501       87       NA       NA
8              NA           NA           NA           NA      223       47       NA       NA


Je veux calculer une médiane pondérée pour chaque ligne (ou j'ai les données bien sur, donc ici la ligne 7)

Mon code est le suivant

Code : Tout sélectionner

medianp<-function(monvec){
  return(weighted.median(x=monvec[1:4], w=monvec[5:8], na.rm=T))
}
median_p<-apply(data.frame(Mp),FUN=medianp,MARGIN=1)


Et R me retourne

Code : Tout sélectionner

 Erreur : All weights are zero


Pouvez vous m'aider à comprendre ou est mon erreur et pourquoi ca ne fonctionne pas?


Merci par avance

Antoine

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: problème calcul médiane pondérée

Messagepar Mickael Canouil » 07 Fév 2019, 10:01

Bonjour,

l'erreur est "évidente" => tous vos poids sont égaux à zéro dans au moins une ligne...

Et faute d'avoir un code reproductible, il est impossible de reproduire votre erreur.
Par exemple, d'où sort la fonction "weighted.median" ?

Qu'est-ce qu'un code reproductible ?
Comment insérer des données dans un message

Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: problème calcul médiane pondérée

Messagepar Pierre-Yves Berrard » 07 Fév 2019, 10:04

Mickael Canouil a écrit :l'erreur est "évidente" => tous vos poids sont égaux à zéro...
1055 = 0 ?
Pour le reste, entièrement d'accord avec Mickaël. ;-)
PY

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: problème calcul médiane pondérée

Messagepar Mickael Canouil » 07 Fév 2019, 10:06

Pierre-Yves Berrard a écrit :
Mickael Canouil a écrit :l'erreur est "évidente" => tous vos poids sont égaux à zéro...
1055 = 0 ?


La fonction medianp() est appliquée ligne par ligne sur le data.frame Mp.
Le jeu de données fournie est partiel, ainsi aucune garantie que les colonnes number_* ait au moins une valeur.
Donc Il est plus que probable qu'une ligne ne contienne aucune valeur (soit des zéros soit des NA, potentiellement équivalent à zéro si na.rm = TRUE) pour les colonnes number_*


EDIT: la phrase complète: l'erreur est "évidente" => tous vos poids sont égaux à zéro dans au moins une ligne...
Mickaël
mickael.canouil.fr | rlille.fr

Antoine Kimmoun
Messages : 2
Enregistré le : 06 Fév 2019, 15:20

Re: problème calcul médiane pondérée

Messagepar Antoine Kimmoun » 07 Fév 2019, 10:30

Rebonjour,

Merci de m'avoir répondu...

Voici le code reproductible de mon df:

Code : Tout sélectionner

df<-structure(list(median_age_1 = c(NA, NA, NA, NA, NA, NA, 83),
               median_age_2 = c(NA, NA, NA, NA, NA, NA, 86), median_age_3 = c(NA_real_,
                                                                              NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_
               ), median_age_4 = c(NA_integer_, NA_integer_, NA_integer_,
                                   NA_integer_, NA_integer_, NA_integer_, NA_integer_), number_1 = c(1055L,
                                                                                                     171L, 235L, 481L, 834L, 92L, 501L), number_2 = c(324L, 170L,
                                                                                                                                                      46L, 810L, 371L, 69L, 87L), number_3 = c(NA, 169L, 79L, NA,
                                                                                                                                                                                               NA, NA, NA), number_4 = c(NA, NA, 113L, NA, NA, NA, NA)), row.names = c("1",
                                                                                                                                                                                                                                                                       "2", "3", "4", "5", "6", "7"), class = "data.frame")


qui done ce df:

Code : Tout sélectionner

 median_age_1 median_age_2 median_age_3 median_age_4 number_1 number_2 number_3 number_4
1           NA           NA           NA           NA     1055      324       NA       NA
2           NA           NA           NA           NA      171      170      169       NA
3           NA           NA           NA           NA      235       46       79      113
4           NA           NA           NA           NA      481      810       NA       NA
5           NA           NA           NA           NA      834      371       NA       NA
6           NA           NA           NA           NA       92       69       NA       NA
7           83           86           NA           NA      501       87       NA       NA


Voici mon "mauvais" code pour essayer d'obtenir une moyenne pondérée

Code : Tout sélectionner

library(spatstat)
medianp<-function(monvec){
  return(weighted.median(x=monvec[1:4], w=monvec[5:8], na.rm=T))
}
median_p<-apply(data.frame(df),FUN=medianp,MARGIN=1)


Et la réponse

Code : Tout sélectionner

 Erreur : All weights are zero


Pouvez vous m'éclairer sur ce que je dois faire?

Merci beaucoup!

Antoine

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: problème calcul médiane pondérée

Messagepar Mickael Canouil » 07 Fév 2019, 10:46

Il s'avère que le message d'erreur proposé par l'auteur de la fonction n'est pas des plus précis.
En effet, l'erreur survient si les valeurs et/ou les poids sont tous à zéro.

Code : Tout sélectionner

weighted.quantile <- function (x, w, probs = seq(0, 1, 0.25), na.rm = TRUE) {
    x <- as.numeric(as.vector(x))
    w <- as.numeric(as.vector(w))
    if (anyNA(x) || anyNA(w)) {
        ok <- !(is.na(x) | is.na(w))
        x <- x[ok]
        w <- w[ok]
    }
    stopifnot(all(w >= 0))
    if (all(w == 0))
        stop("All weights are zero", call. = FALSE)
...
}


Sur le principe, calculer quoique ce soit d'un vecteur de NA, comme c'est le cas pour vos six premières lignes, n'a pas vraiment de sens...
Pour n'autoriser le calcul que s'il y a au moins une valeur et un poids:

Code : Tout sélectionner

medianp <- function(monvec) {
  if (all(is.na(monvec[1:4])) | all(is.na(monvec[5:8]))) {
    return(NA)
  } else {
    return(weighted.median(x = monvec[1:4], w = monvec[5:8], na.rm = TRUE))
  }
}


Pour avoir un code un peu plus "robuste":

Code : Tout sélectionner

library(purrr)
library(spatstat)

df <- structure(
  list(
    median_age_1 = c(NA, NA, NA, NA, NA, NA, 83),
    median_age_2 = c(NA, NA, NA, NA, NA, NA, 86),
    median_age_3 = c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_),
    median_age_4 = c(NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_),
    number_1 = c(1055L, 171L, 235L, 481L, 834L, 92L, 501L),
    number_2 = c(324L, 170L, 46L, 810L, 371L, 69L, 87L),
    number_3 = c(NA, 169L, 79L, NA, NA, NA, NA),
    number_4 = c(NA, NA, 113L, NA, NA, NA, NA)
  ),
  row.names = c("1", "2", "3", "4", "5", "6", "7"),
  class = "data.frame"
)

medianp <- function(monvec) {
  x <- monvec[grep("median_age", names(monvec))]
  y <- monvec[grep("number", names(monvec))]
  if (all(is.na(x)) | all(is.na(y))) {
    return(NA)
  } else {
    return(spatstat::weighted.median(x = x, w = y, na.rm = TRUE))
  }
}

df[, "weighted_median"] <- sapply(X = purrr::transpose(df), FUN = medianp)
Mickaël
mickael.canouil.fr | rlille.fr

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: problème calcul médiane pondérée

Messagepar Pierre-Yves Berrard » 07 Fév 2019, 10:46

En jetant un oeil au code source de weighted.median, on peut voir que la fonction ne considère que les couples ou à la fois la valeur et le poids sont non manquantes. Pour la ligne 1 par exemple, cette condition n'est pas remplie.

Et sinon, est-il possible en théorie de reconstituer une médiane globale à partir des médianes de sous-groupes, comme vous semblez vouloir le faire ? Même si c'est possible, je ne suis pas sûr que la fonction weighted.median réponde à ce besoin.
PY


Retourner vers « Questions en cours »

Qui est en ligne

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