R 金额(仅限整数)在不同存储桶上的分布组合
假设一个有5个存储桶(1-5),并且为每个存储桶分配一个(整数)值。例如R 金额(仅限整数)在不同存储桶上的分布组合,r,R,假设一个有5个存储桶(1-5),并且为每个存储桶分配一个(整数)值。例如 > bucket = 1:5 > value = c(14, 12, 9, 20, 7) > data.frame(bucket, value) bucket value 1 1 14 2 2 12 3 3 9 4 4 20 5 5 7 然后,要求一个人将bucket的值总共增加3(只允许整数增加)。有几种方法可以在
> bucket = 1:5
> value = c(14, 12, 9, 20, 7)
> data.frame(bucket, value)
bucket value
1 1 14
2 2 12
3 3 9
4 4 20
5 5 7
然后,要求一个人将bucket的值总共增加3(只允许整数增加)。有几种方法可以在这些桶上分配总共3个(只允许整数增加)
R中是否有一个函数给出了5个桶上总共3个桶的所有可能分布
更具体地说,类似于:
distr1 distr2 distr3 distr4 distr5 distr6 ....
1 3 2 2 2 2 1 ....
2 0 1 0 0 0 2 ....
3 0 0 1 0 0 0 ....
4 0 0 0 1 0 0 ....
5 0 0 0 0 1 0 ....
我研究了
combn()
和expand.grid()
,但这些函数似乎并不合适……这里有一种可能性,使用expand.grid
,可能不是最优雅的:
n_buckets <- 5
increase <- 3
foo <- do.call(
expand.grid,
replicate(increase, seq_len(n_buckets), simplify = FALSE)
)
res <- apply(foo, 1, function(x) {
sapply(seq_len(n_buckets), function(y) sum(y == x))
})
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
# [1,] 3 2 2 2 2 2 1 1 1 1 2
# [2,] 0 1 0 0 0 1 2 1 1 1 0
# [3,] 0 0 1 0 0 0 0 1 0 0 1
# [4,] 0 0 0 1 0 0 0 0 1 0 0
# [5,] 0 0 0 0 1 0 0 0 0 1 0
# [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
# [1,] 1 1 1 1 2 1 1 1 1
# [2,] 1 0 0 0 0 1 0 0 0
# [3,] 1 2 1 1 0 0 1 0 0
# [4,] 0 0 1 0 1 1 1 2 1
# [5,] 0 0 0 1 0 0 0 0 1
#
# ...
使用
网格。展开以确定可以调用哪些箱子
I <- expand.grid(1:5,1:5,1:5)
输出
请注意,我的输出也应按行读取:
首先,我们创建值0-3的所有可能组合(invec
),然后使用rowSums
,仅选择在所有存储桶中总和为3的组合:
incvec <- 0:3
allDists <- expand.grid(b1=incvec,b2=incvec,b3=incvec,b4=incvec,b5=incvec)
finDists <- allDists[rowSums(allDists) == 3,]
> head(finDists)
b1 b2 b3 b4 b5
4 3 0 0 0 0
7 2 1 0 0 0
10 1 2 0 0 0
13 0 3 0 0 0
19 2 0 1 0 0
22 1 1 1 0 0
...
incvec我不使用提供map\u df
的库,但感谢您提供此解决方案。
library(purrr)
library(tidyr)
dist_df <- map_df(1:nrow(I), ~ as.data.frame(table(unlist(I[.x,]))) %>% spread(Var1,Freq)) %>%
replace(is.na(.), 0)
1 2 3 4 5
1 3 0 0 0 0
2 2 1 0 0 0
3 2 0 1 0 0
4 2 0 0 1 0
5 2 0 0 0 1
incvec <- 0:3
allDists <- expand.grid(b1=incvec,b2=incvec,b3=incvec,b4=incvec,b5=incvec)
finDists <- allDists[rowSums(allDists) == 3,]
> head(finDists)
b1 b2 b3 b4 b5
4 3 0 0 0 0
7 2 1 0 0 0
10 1 2 0 0 0
13 0 3 0 0 0
19 2 0 1 0 0
22 1 1 1 0 0
...