2017-06-27 3 views
0

J'ai une grande table où j'ai calculé le nombre de comptes par sous-catégorie countsperc (noms sous-catégorie non représentés) pour toutes les catégories (id), puis la totale d'observations par catégorie (id) dans la colonne sumofcounts, et la proportion de la sous-catégorie à le total (counsperc/sumofcounts) en apppropor (proportions approximatives), qui doit être approximative (3 décimales).
Le problème est, la somme des proportions approximatives (old_sum) pour les catégories (id) doit être 1.000 au lieu de 0.999, etc.
Alors, je voudrais demander une méthode pour ajouter ou soustraire 0,001, sur un sous -item de la colonne apppropor afin d'obtenir 1.000 toujours comme somme. Par exemple, dans row1 le nombre pourrait être 0,334 au lieu de 0,333
EDIT: Le but de la tâche n'est pas de produire uniquement une somme exacte de 1, qui n'a aucune utilité, mais de produire une entrée à un autre programme, ce qui considérez la colonne apppropor telle quelle (ce qui nécessitera une somme de 1.000 par id, voir le message d'erreur ci-dessous).proportions approximatives en préservant la somme (1 = 100%) en R

text1<-" 
id countsperc sumofcounts apppropor  
item1   1   3  0.333  
item1   1   3  0.333  
item1   1   3  0.333  
item2   1   121  0.008  
item2  119   121  0.983  
item2   1   121  0.008  
item3   1   44  0.023  
item3   1   44  0.023  
item3   41   44  0.932  
item3   1   44  0.023  
item4   1   29  0.034  
item4   3   29  0.103  
item4   1   29  0.034 
item4   24   29  0.828" 
table1<-read.table(text=text1,header=T) 
library(data.table) 
sums<-as.data.frame(setDT(table1)[, sum(`apppropor`), by = .(id)][,.(id, old_sum = V1)]) 
table1<-merge(table1,sums) 
table1 

chromEvol Version: 2.0. Dernière mise à jour Décembre 2013

Les probabilités de comptage pour les taxons Ad_mic ne pas totaliser 1,0 chromEvol: errorMsg.cpp: 41: errorMsg static void :: reportError (string const &, int): Assertion `0' a échoué. Aborted (core dumped)

Répondre

0

J'ai trouvé un moyen.

table1$dif<-1-table1$old_sum 
table1<-table1[order(table1$id),] 
len<-rle(as.vector(table1$id))[[1]] 
table1$apppropor[cumsum(len)]<-table1$apppropor[cumsum(len)]+table1$dif[cumsum(len)] 
#verify 
library(data.table) 
sums<-as.data.frame(setDT(table1)[, sum(`apppropor`), by = .(id)][,.(id, new_sum = V1)]) 
table1<-merge(table1,sums) 
table1 
0

Si vous avez besoin sum_of_prop être identique égale à 1 dans chaque ligne, vous calculez la mauvaise façon. Vous n'ajoutez pas 0.333 + 0.333 + 0.333 et vous forcez cette somme à 1. Vous ajoutez (1/3) + (1/3) + (1/3) et la somme est en réalité 1.

en supposant qu'aucune autre colonne peut changer, essayez le calcul sum_of_prop comme ceci:

n <- length(table1$id) 
new_sum_of_prop <- rep(0, n) 
for (i in 1:n) { 
    tempitem <- table1$id[i] 
    tempsum <- sum(table1$countsperc[(table1$id == tempitem)]) 
    new_sum_of_prop[i] <- table1$sumofcounts[i]/tempsum 
} 

table2 <- as.data.frame(cbind(table1, new_sum_of_prop)) 
table2 
     id countsperc sumofcounts apppropor sum_of_prop new_sum_of_prop 
1 item1   1   3  0.333  0.999    1 
2 item1   1   3  0.333  0.999    1 
3 item1   1   3  0.333  0.999    1 
4 item2   1   121  0.008  0.999    1 
5 item2  119   121  0.983  0.999    1 
6 item2   1   121  0.008  0.999    1 
7 item3   1   44  0.023  1.001    1 
8 item3   1   44  0.023  1.001    1 
9 item3   41   44  0.932  1.001    1 
10 item3   1   44  0.023  1.001    1 
11 item4   1   29  0.034  0.999    1 
12 item4   3   29  0.103  0.999    1 
13 item4   1   29  0.034  0.999    1 
14 item4   24   29  0.828  0.999    1 

Je comprends que ce n'est pas exactement ce que vous avez demandé, mais à long terme, vos résultats sont toujours en meilleure santé si vous ne faites pas couper les coins mathématiques le long du chemin.

+0

merci, mais l'accent est la colonne apppropor. voir modifier. – Ferroao