Comment calculer une mise en commun de l'écart type dans R?
Je veux calculer la mise en commun (en fait, pondéré a) l'écart-type pour tous les sites uniques dans mon bloc de données.
Les valeurs de ces sites sont des valeurs pour une seule espèce peuplements forestiers et je veux de la piscine de la moyenne et de la carte sd pour que je puisse comparer les peuplements de feuillus avec des peuplements de résineux.
C'est la trame de données (df) avec des valeurs pour les peuplements de feuillus:
keybl n mean sd
Vest02DenmDesp 3 58.16 6.16
Vest02DenmDesp 5 54.45 7.85
Vest02DenmDesp 3 51.34 1.71
Vest02DenmDesp 3 59.57 5.11
Vest02DenmDesp 5 62.89 10.26
Vest02DenmDesp 3 77.33 2.14
Mato10GermDesp 4 41.89 12.6
Mato10GermDesp 4 11.92 1.8
Wawa07ChinDesp 18 0.097 0.004
Chen12ChinDesp 3 41.93 1.12
Hans11SwedDesp 2 1406.2 679.46
Hans11SwedDesp 2 1156.2 464.07
Hans11SwedDesp 2 4945.3 364.58
Keybl est le code pour le site. La formule pour la mise en commun des SD est:
s=sqrt((n1-1)*s1^2+(n2-1)*s2^2)/(n1+n2-2))
(Désolé, je ne peux pas poster de photos et de ne pas trouver un lien qui permettrait d'aller directement à la formule)
Où 2 est le nombre de groupes et donc de changer en fonction sur le site. Je sais que c'est utilisé pour les t-test, et deux groupes on veut comparer. Dans ce cas, je n'ai pas l'intention de comparer ces groupes. Mon professeur m'a suggéré d'utiliser cette formule pour obtenir une pondéré sd. Je n'ai pas trouvé une fonction R qui intègre cette formule dans la façon dont j'en ai besoin, donc j'ai essayé de construire mon propre. Je suis, cependant, de nouvelles R et pas très bon à la réalisation des fonctions et des boucles, donc j'espère pour votre aide.
C'est ce que j'ai obtenu jusqu'à présent:
sd=function (data) {
nc1=data[z,"nc"]
sc1=data[z, "sc"]
nc2=data[z+1, "nc"]
sc2=data[z+1, "sc"]
sd1=(nc1-1)*sc1^2 + (nc2-1)*sc2^2
sd2=sd1/(nc1+nc2-length(nc1))
sqrt(sd2)
}
splitdf=split(df, with(df, df$keybl), drop = TRUE)
for (c in 1:length(splitdf)) {
for (i in 1:length(splitdf[[i]])) {
a = (splitdf[[i]])
b =sd(a)
}
}
1) La fonction elle-même n'est pas correct, car il donne légèrement plus faible des valeurs qu'il ne le devrait et je ne comprends pas pourquoi. Se pourrait-il qu'il ne s'arrête pas lorsque z+1 a atteint la dernière ligne? Si oui, comment peut-elle être corrigée?
2) La boucle est totalement faux mais c'est ce que j'ai pu arriver au bout de plusieurs heures sans aucun succès.
Quelqu'un peut-il m'aider?
Merci,
Antra
OriginalL'auteur Antra | 2013-06-07
Vous devez vous connecter pour publier un commentaire.
La mise en commun des SD sous l'hypothèse d'indépendance (de sorte que les termes de covariance peut être supposée égale à zéro) sera: sqrt( sum_over_groups[ (var)/somme(n)-N_groups)] )
lapply+split
~by
? 😉Je ne reçois pas de crédit pour reconnaître que la croix de la variance des termes doit être supposée égale à zéro? De votre point de vue: j'ai parfois l'éviter, car il aurait besoin
do.call(rbind(.))
à tirer de nouveau ensemble et il semble maladroit (3 fonctions au lieu de deux), mais qui pourrait être bien comme " sapply(split () ()' ici. Une question de style, je pense.Merci beaucoup. Cette réponse fonctionne bien et est beaucoup mieux par rapport à ce que j'avais à l'esprit. J'ai seulement ajouté (jj$n-1) pour la fonction que la sd doit être multiplié par n-1. somme( jj$sd^2 * (jj$n-1) )
Il superficiellement semble meilleure, mais il y a clairement une erreur étant donné que Wawa07ChinDesp devrait être la même que la valeur d'origine, car il n'y a rien à la piscine. Il semble être correcte que df est toujours 2. Une solution facile devrait être d'utiliser le dd$n-1 dans le dénominateur est la somme (.../ somme(jj$n-1)).
Édité. Aussi me semble qu'il pourrait être erronée à tout moment il y a un seul élément des groupes. Pas sûr "variance" fait beaucoup de sens dans ces situations, de toute façon.
OriginalL'auteur 42-
Ce que vous essayez de faire serait de bénéficier d'une formule plus générale, ce qui va rendre plus facile. Si vous n'avez pas besoin de le casser en morceaux par le keybl variable que vous auriez fait.
Un principe général important dans R, c'est que vous utilisez vecteur de maths autant que possible. Dans ce cas trivial, il ne sera pas question beaucoup de choses, mais pour voir comment faire cela sur de grandes
data.frame
objets où le calcul de la vitesse est plus important, à lire sur.Et maintenant il suffit d'utiliser les fonctions de confort de fractionnement et de calculer les sommes nécessaires. Remarque une seule fonction est exécutée ici dans chaque boucle implicite (*appliquer, d'agrégation, etc. sont toutes les boucles implicites pour exécuter des fonctions à de nombreuses reprises).
Et la bonne réponse est:
Cela semble beaucoup moins concis que les autres méthodes (comme 42-'s réponse), mais si vous déroulez ceux en termes de nombre de R commandes sont exécutées c'est beaucoup plus concis. Pour un court laps de problème comme ça de toute façon c'est bien, mais j'ai pensé que je devais vous montrer la méthode qui utilise le plus le vecteur de mathématiques. Il met également en lumière pourquoi ces pratiques boucle implicite fonctions sont disponibles, pour l'expressivité. Si vous avez utilisé
for
boucles d'accomplir la même chose, alors la tentation serait forte de tout mettre dans la boucle. Cela peut être une mauvaise idée dans l'arrêt R.n-1
à la volée?sqrt( sum(df$sd^2 * (df$n - 1)) / (sum(df$n - 1)) )
J'ai élargi la réponse afin de rendre cela plus clair.
OriginalL'auteur John