1
votes

Valeur moyenne uniquement des données comprises entre le 1er et le 3ème quartile de R

J'ai des valeurs de concentration pour différents effets, et j'ai essayé de calculer les valeurs moyennes pour chaque ensemble de données groupées (par différents effets), mais uniquement pour les données contenues entre le 1er et le 3ème quartile d'un boxplot, en utilisant R. J'ai d'abord fait les boîtes à moustaches (avec ggplot) mais je ne vois pas comment cela pourrait aider. Avec la fonction ggplot_build (), j'obtiens juste les quartiles. J'ai aussi essayé "aggregate ()", mais cela fournit la moyenne de l'ensemble complet, et je ne veux pas inclure ce qui est en dehors des 1er et 3ème quartiles. Des idées? Merci de votre aide.

 conc.value Conc.units Effect.group           Effect
1    0.000160000    AI mg/L    systemic        Physiology
2    0.000560000    AI mg/L    systemic        Population
3    0.001090377    AI mg/L    systemic        Population
4    0.001124100    AI mg/L   cell-based        Enzyme(s)
5    0.001686150    AI mg/L    systemic        Population
6    0.002000000    AI mg/L    systemic        Population
7    0.002000000    AI mg/L    systemic        Population
8    0.002000000    AI mg/L    systemic        Population
9    0.002248200    AI mg/L   cell-based        Enzyme(s)
10   0.002248200    AI mg/L   cell-based        Enzyme(s)
11   0.002248200    AI mg/L    systemic        Population
12   0.002248200    AI mg/L   cell-based     Biochemistry
13   0.004000000    AI mg/L    systemic        Population
14   0.004000000    AI mg/L    systemic        Population
15   0.004496400    AI mg/L   cell-based     Biochemistry
16   0.004496400    AI mg/L   cell-based        Enzyme(s)
17   0.004496400    AI mg/L    systemic        Population
18   0.005000000    AI mg/L    systemic        Population
19   0.005000000    AI mg/L    systemic        Population
20   0.005000000    AI mg/L    systemic        Population
21   0.005000000    AI mg/L    systemic        Population
22   0.005000000    AI mg/L    systemic        Population
23   0.005000000    AI mg/L    systemic        Population
24   0.005000000    AI mg/L    systemic        Population
25   0.005000000    AI mg/L    systemic        Population
26   0.005000000    AI mg/L    systemic        Population


0 commentaires

3 Réponses :


1
votes

Vous pouvez accéder aux statistiques incluses dans les boxplots. Voici quelques données illustratives:

tapply(df$V1, df$Effect, function(x)  mean(x[x >= quantile(x, 0.25) & x <= quantile(x, 0.75)]))
           A            B            C            D 
 0.005502653  0.251196882  0.077304685 -0.108590409

Maintenant, stockez le boxplot de votre colonne V1 sous forme d'objet, appelé ici, eh bien, objet :

set.seed(123)
df <- data.frame(
  V1 = c(rnorm(100)),
  Effect = sample(LETTERS[1:4], 100, replace = T)
)

Inspecter les statistiques associées en interne à object:

set.seed(123)
df <- data.frame(
  V1 = c(rnorm(100)),
  V2 = c(rnorm(100, 1)),
  V3 = c(rnorm(100, 2))
)

lapply(df[,1:3], function(x)  mean(x >= object$stats[2] & x <= object$stats[4]))
$V1
[1] 0.5

$V2
[1] 0.39

$V3
[1] 0.07

Les 2ème et 4ème valeurs délimitent l'IQR (pour vérifier, vous pouvez faire summary (df) ). La prochaine étape serait donc de sous-ensemble df $ V1 sur ces deux valeurs et de calculer la moyenne:

mean(df$V1 >= object$stats[2] & df$V1 <= object$stats[4])
[1] 0.5

Ceci est, in nuce , comment vous pouvez résoudre le problème. Comme il semble que vous ayez un dataframe plus complexe que celui-ci, cette solution devra évidemment être adaptée à vos données. Si vous avez besoin d'aide, vous devez montrer à quoi ressemblent les données.

Par exemple, si vous avez un dataframe avec plusieurs variables numériques, vous pouvez faire le calcul en une fois comme ceci: p>

object$stats
            [,1]
[1,] -1.96661716
[2,] -0.49667731
[3,]  0.06175631
[4,]  0.69499808
[5,]  2.18733299

MODIFIER :

Pour un ensemble de données tel que celui que vous décrivez dans votre commentaire récent, la solution pourrait être la suivante:

object <- boxplot(df$V1)

Pour calculer la moyenne de l'intervalle interquartile par Effet , vous pouvez le faire en une seule fois:

set.seed(123)
df <- data.frame(
  V1 = c(rnorm(100))
)


9 commentaires

Dans votre exemple, quand vous faites "mean (df $ V1> = object $ stats [2] & df $ V1 <= object $ stats [4])", comment pouvez-vous dire que le résultat 0.5 incluait tous les points de données entre le 1er et 3e quartile? Comme je le vois ici, vous ne faites que sous-définir la valeur numérique spécifique des quartiles, et non les données qu'elle contient.


Non, notez l'utilisation de > = et <= : mean (df $ V1> = object $ stats [2] & df $ V1 <= object $ stats [4]) dit: calculez la moyenne de cette plage de df $ V1 qui est supérieure ou égale à object $ stats [2] et plus petite supérieur ou égal à object $ stats [4] . Autrement dit, vous sous-définissez df $ V1 sur ces deux valeurs numériques.


Voir EDIT dans la réponse.


Et si j'ai 20 valeurs identiques, puis d'autres valeurs différentes. Si je le fais, "signifie (df $ V1> = object $ stats [2] ...". Le logiciel ne comprendrait-il pas "toutes ces valeurs qui sont égales à cette valeur spécifique (le 1er quartile)", peu importe comment Cela affectera certainement la valeur moyenne.


Mais c'est la nature de la façon dont la moyenne est calculée! Il ne distingue pas les valeurs identiques et différentes. La moyenne est une mesure de la tendance centrale et si certaines valeurs se répètent, cette répétition aura bien sûr un impact sur la moyenne, et à juste titre!


Mon commentaire a été mal compris. Lorsque vous tapez ce code: "mean (df $ V1> = object $ stats [2] & df $ V1 <= object $ stats [4])". Vous ne dites pas que "object $ stats [4]" est un quartile mais un simple nombre. Ensuite, si les données contiennent des valeurs répétitives, le code prendra même celles qui sont en dehors des quartiles car elles sont numériquement identiques. Prenons cet exemple simple: data = 2,4,7,7,7,7,7,9,9,9,15,15,15,15; 1er q = 7, 3e q = 15. Si je fais: mean (df $ V1> = object $ stats [2] & df $ V1 <= object $ stats [4]), cela prendra:> = 7 & <= 15. Alors, le résultat moyen sera = 10,17, mais c'est en fait 8,75. J'espère que je pourrais être clair


D'accord, si vous avez des données <- c (2,4,7,7,7,7,7,9,9,9,15,15,15,15) , alors quant <- quantile (data) suivi de mean (data [data> = quant [2] & data <= quant [4]]) vous donne ce que vous voulez. Je mettrai à jour ma réponse.


@ user1407 Je vous serais reconnaissant de bien vouloir me faire savoir si la dernière solution fonctionne pour vous.


J'ai utilisé un sous-ensemble pour diviser mon ensemble de données par effets. Ensuite, j'ai utilisé votre code "quant <- quantile (data) suivi de mean (data [data> = quant [2] & data <= quant [4]])" pour calculer la moyenne des données contenues dans l'IQR, pour chaque effet grouper. Merci beaucoup pour votre aide!



1
votes

J'utiliserais la fonction quantile . En utilisant les mêmes données que @Chris

> quantile(df$V1,probs=.25)
       25% 
-0.4938542 

Vous pouvez obtenir les valeurs, par l'index quantile (df $ V1) [1] ou en utilisant le option probs

quantile(df$V1)
         0%         25%         50%         75%        100% 
-2.30916888 -0.49385424  0.06175631  0.69181917  2.18733299 

Une fois que vous avez les données, sous-ensemble et calculez simplement la moyenne (comme @Chris) l'a indiqué


0 commentaires

0
votes

Je créerais d'abord une nouvelle fonction qui génère le groupe de quantiles de chaque élément dans un vecteur donné:

> dt[Qnums %in% c(2,3), mean(nums)]
[1] 0.05432868

> mean(df$nums[df$Qnums %in% c(2,3)])
[1] 0.05432868

Maintenant, appliquez cette fonction sur un vecteur numérique nums code > dans une data.table ou data.frame:

set.seed(123)
nums = rnorm(100)

#data.table
dt = data.table(nums)[, Qnums := qgroup(nums)]

#data.frame
df = data.frame(nums)
df$Qnums = qgroup(df$nums)

Enfin, sous-ensemble l'objet de données selon Qnums et calculez la moyenne de la colonne numérique nums:

qgroup = function(numvec, n = 4){

  qtile = quantile(numvec, probs = seq(0, 1, 1/n), na.rm = T)
  out = sapply(numvec, function(x) sum(x >= qtile[-(n+1)]))

  return(out)
}

> qgroup(seq(1:20))
 [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4


0 commentaires