我有一个简单的模型,公司有两个农场,每个农场种植两种作物(苹果和梨)。第一步就是把树的数量乘以每棵树上的果实数量。在
每棵树上的果实数量是模拟的(跨农场和作物)。在
在R中建模时,我至少要面对三个决策:
即使我添加了另一种作物和/或农场,我也希望它能起作用——理想情况下,即使我添加了另一个维度,例如作物品种(Granny Smith等)。我还想用名字来指农场和农作物,而不是用索引号。在
这是我想出的方法。它是可行的,但是很难添加另一个维度,而且需要大量的代码。有更整洁的方法吗?在
要构建变量:
farms <- c('Farm 1', 'Farm 2');
crops <- c('Pear', 'Apple');
params <- c('mean','sd');
numTrees <- array(0, dim=c(length(farms), length(crops)), dimnames=list(farms,crops));
fruitPerTree <- array(0, dim=c(length(farms), length(varieties), length(params)),
dimnames=list(farms,varieties,params));
# input data e.g.
numTrees['Farm 1', 'Pear'] = 100
# and
fruitPerTree['Farm 1', 'Pear', 'mean'] = 50
要模拟:
^{pr2}$要将simFruitPerTree
和numTrees
相乘,我发现首先必须执行手动广播:
simNumTrees <- array(numTrees, dim=c(length(dims[[1]]), length(dims[[2]]), numSims),
dimnames=list(dims[[1]], dims[[2]], c(1:numSims)));
simTotalFruit <- simFruitPerTree * simNumTrees;
为了进行比较,在Python中(我比R更了解它),我可以在几行代码中执行所有这些步骤,方法是使用元组索引字典,以及两种字典理解,例如:
fruit_per_tree = {}
fruit_per_tree[('Farm 1', 'Pear')] = (50, 15) # normal params
sim_fruit_per_tree = {key: random.normal(*params, size=num_sims)
for key, params in fruit_per_tree.items() }
sim_total_fruit = {key: sim_fruit_per_tree[key]*num_trees[key] for key in num_trees }
在R里也有简单的方法吗?谢谢!在
如果我没弄错的话,你是在建模n个农场的水果总产量,每个农场有k种作物(这里,n=k=2)。每个农场都有一定数量的每种树木,每个农场的生产力(果实/树)是分布在N(μ,σ)上的随机变量,其中μ和σ取决于农场和品种。在
所以对于输入,我们构造一个数据帧,
params
,有5列:farm, crop, trees, mean, and sd
。然后每行包含树的数量,每棵树的平均生产力,和每棵树在给定的农场/作物组合中的生产力变化。这些是输入。在如果我们在树的水平上建模,那么给定农场中给定品种的每棵树的果实产量为:
也就是说,输出是长度=树的随机样本,平均值和标准差适用于给定的品种和农场。那么这个品种/农场的所有树木的总产量就是上面向量的和,总产量就是所有农场/作物的总和。在
所有这些都给了我们蒙特卡罗模型的1迭代。为了确定总产出的分布,我们必须重复这个过程若干次。幸运的是,在R中这是相当简单的:
^{pr2}$这个代码对于农场或品种的数量是不可知的;只需在开头更改}向量。如果不是所有农场都有所有的品种,请为缺失的品种设置
farms
和{params$trees <- 0
。在我们可以检查
n.iterations
的影响,如下所示。这段代码只运行完整的模拟100、1000和10000次,并使用ggplot
绘制分布图。在最后,我建议您考虑每棵树的输出比正常情况下更可能是泊松分布。如果使用
rpois(...)
而不是rnorm(...)
重新运行模拟,则总体sd略低(约150而不是~200)。在这是我问题的一般解决办法。我从罗兰的方法开始,并对其进行了更新,使分布、参数和尺寸都可以轻松更改。在
示例用法(仅为简单起见,使用正态分布):
^{pr2}$样本输出:
还请注意,您还可以以一种良好的索引方式定义输入值;例如,如果您定义
然后
c(numTrees)
对其输出排序的方式与expand.grid
相匹配,因此可以将constList = list(numTrees=c(numTrees2)
传递给distSim
。在下面是我如何设置这样的模拟:
相关问题 更多 >
编程相关推荐