R:如何得到两个分布的总和?

时间:2015-12-08 22:51:56

标签: r sum distribution

我有一个简单的问题。 我想总结两个非参数分布。

这是一个例子。 有两个城市有10个房子。我们知道每个房子的能源消耗。 (编辑)我想得到从每个城市中选择的随机房屋总和的概率分布。

A1 <- c(1,2,3,3,3,4,4,5,6,7) #10 houses' energy consumption for city A
B1 <- c(11,13,15,17,17,18,18,19,20,22) #10 houses' energy consumption for city B

我有A1和B1的概率分布,我怎样才能得到A1 + B1的概率分布? 如果我只在R中使用A1+B1,则会给出12 15 18 20 20 22 22 24 26 29。但是,我不认为这是对的。因为房子没有订单。

当我改变房屋的顺序时,会产生另一个结果。

# Original
A1 <- c(1,2,3,3,3,4,4,5,6,7)
B1 <- c(11,13,15,17,17,18,18,19,20,22)
#change order 1
A2 <- c(7,6,5,4,4,3,3,3,2,1) 
B2 <- c(22,20,19,18,18,17,17,15,13,11)
#change order 2
A3 <- c(3,3,3,4,4,5,6,7,1,2) 
B3 <- c(17,17,18,18,19,13,20,11,22,15)
sum1 <- A1+B1; sum1
sum2 <- A1+B2; sum2
sum3 <- A3+B3; sum3

enter image description here

红线是sum1,sum2和sum3。我不知道如何分配两个发行版的总和。请给我任何想法。谢谢!

(如果这些分布是正态分布或均匀分布,我可以很容易得到分布的总和,但这些不正常,没有顺序)

4 个答案:

答案 0 :(得分:5)

理论上,两个随机变量的和分布是它们的PDF卷积details,如下:

  

PDF(Z)= PDF(Y)* PDF(X)

所以,我认为这种情况可以通过convolution来计算。

# your data
A1 <- c(1,2,3,3,3,4,4,5,6,7) #10 houses' energy consumption for city A
B1 <- c(11,13,15,17,17,18,18,19,20,22) #10 houses' energy consumption for city B

# compute PDF/CDF
PDF_A1 <- table(A1)/length(A1)
CDF_A1 <- cumsum(PDF_A1)

PDF_B1 <- table(B1)/length(B1)
CDF_B1 <- cumsum(PDF_B1)

# compute the sum distribution 
PDF_C1 <- convolve(PDF_B1, PDF_A1, type = "open")

# plotting
plot(PDF_C1, type="l", axe=F, main="PDF of A1+B1")
box()
axis(2)
# FIXME: is my understand for X correct?
axis(1, at=seq(1:14), labels=(c(names(PDF_A1)[-1],names(PDF_B1))))

enter image description here

注意:

  

CDF:累积分配函数

     

PDF:概率密度函数

## To make the x-values correspond to actually sums, consider
## compute PDF
## pad zeros in probability vectors to convolve
r <- range(c(A1, B1))
pdfA <- pdfB <- vector('numeric', diff(r)+1L)
PDF_A1 <- table(A1)/length(A1)                        # same as what you have done
PDF_B1 <- table(B1)/length(B1)
pdfA[as.numeric(names(PDF_A1))] <- as.vector(PDF_A1)  # fill the values
pdfB[as.numeric(names(PDF_B1))] <- as.vector(PDF_B1)

## compute the convolution and plot
res <- convolve(pdfA, rev(pdfB), type = "open")
plot(res, type="h", xlab='Sum', ylab='')

enter image description here

## In this simple case (with discrete distribution) you can compare
## to previous solution
tst <- rowSums(expand.grid(A1, B1))
plot(table(tst) / sum(as.vector(table(tst))), type='h')

enter image description here

答案 1 :(得分:3)

修改

既然我已经更好地理解了这个问题,并且看到了@jeremycg的回答,我认为我有一种不同的方法,我认为这种方法可以更好地扩展样本量。

我们可以推断这些只是分布中的样本,而不是依赖A1B1中的值作为分布中的唯一值。为了避免在分布上强加特定形式,我将使用经验“等价”:样本密度。如果我们使用density函数,我们可以推断从任一城镇采样连续范围的家庭能源使用的相对概率。我们可以从density()$x值中随机抽取任意数量的能量(替换),其中我们采用的sample加权prob=density()$y ...即,密度图是x值,应该更频繁地重新采样。

作为一种启发式方法,过于简单的陈述可以说mean(A1)是3.8,mean(B1)是17,所以两个城市的能源使用总和平均应该是~20.8。使用它作为“有意义测试”/启发式,我认为以下方法与您想要的结果类型一致。

sample_sum <- function(A, B, n, ...){
    qss <- function(X, n, ...){
        r_X <- range(X)
        dens_X <- density(X, ...)
        sample(dens_X$x, size=n, prob=dens_X$y, replace=TRUE)
    }

    sample_A <- qss(A, n=n, ...)
    sample_B <- qss(B, n=n, ...)

    sample_A + sample_B
}

ss <- sample_sum(A1, B1, n=100, from=0)

png("~/Desktop/answer.png", width=5, height=5, units="in", res=150)
plot(density(ss))
dev.off()

请注意,我将密度图限制在0,因为我假设您不想推断负能量。我看到合成密度的峰值刚好超过20,所以“它才有意义”。

这里的潜在优势是,您无需查看两个城市房屋的每种可能的能源组合,以了解总能源使用的分布情况。如果您可以定义两者的分布,则可以定义配对总和的分布。

最后,计算时间是微不足道的,特别是比较了找到所有组合的方法。例如,每个城市有1000万个房屋,如果我尝试expand.grid方法,我会收到Error: cannot allocate vector of size 372529.0 Gb错误,而sample_sum方法需要0.12秒。

当然,如果答案对你没有帮助,那么速度就毫无价值;)

enter image description here

答案 2 :(得分:2)

您可能需要以下内容:

rowSums(expand.grid(A1, B1))

使用expand.grid可以获得A1和B1的所有组合的数据框,rowSums将添加它们。

答案 3 :(得分:0)

在添加之前对分布进行排序是否可以解决此问题?

A1 <- c(1,2,3,3,3,4,4,5,6,7) #10 houses' energy consumption for city A
B1 <- c(11,13,15,17,17,18,18,19,20,22) #10 houses' energy consumption for city B
sort(A1)+sort(B1)