R中的近似比例保留和(1 = 100%)

approximate proportions preserving sum (1 = 100%) in R

我有一个大 table,其中我按子类别 countsperc 计算了计数(子类别名称未显示) 对于每个类别 (id),则总数 sumofcounts 列中每个类别 (id) 的观察值,以及子类别的比例 apppropor 中的总数 (counsperc/sumofcounts)(大约比例),需要近似(小数点后 3)。
问题是,类别 (id) 的近似比例总和 (old_sum) 必须是 1.000 而不是 0.999,等等
所以,我想寻求一种方法,在 apppropor 列的任何子项上添加或减去 0.001,以便始终获得 1.000 作为总和。 例如,在第 1 行中,数字可能是 0.334 而不是 0.333
编辑:该任务的目标不是仅仅产生 1 的精确总和,这没有任何用处,而是产生对其他程序的输入,该程序将按原样考虑列 apppropor (要求它的总和为 1.000根据 id,请参阅下面的错误消息)。

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. Last updated December 2013

The count probabilities for taxa Ad_mic not sum to 1.0 chromEvol: errorMsg.cpp:41: static void errorMsg::reportError(const string&, int): Assertion `0' failed. Aborted (core dumped)

如果您需要 sum_of_prop 在每一行中都等于 1,那么您的计算方式有误。您不添加 0.333 + 0.333 + 0.333 然后强制该总和为 1。您添加 (1/3) + (1/3) + (1/3) 然后总和实际上是 1.

假设没有其他列可以更改,尝试这样计算 sum_of_prop

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

我知道这并不完全符合您的要求,但从长远来看 运行,如果您不在数学上偷工减料,您的结果总是会更健康。

我找到方法了。

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