【发布时间】:2017-02-18 23:31:33
【问题描述】:
我是 StackOverflow 的新手,尽管我玩 R 已经有一段时间了。我正在努力解决一个我无法在网站上找到任何答案的问题。如果我的任务不够准确,请纠正我。
我有两个 3d 数组,在这个简化的例子中是 256x256x200。第一个是一个字段,第二个由索引组成,范围从 1 到 8。我想根据索引的值和计数计算每个垂直级别的平均值,即 200 个级别的字段的平均值对于每个索引(从 1 到 8)。仅当有足够的索引计数(即循环内的 if 条件)时才应执行此操作。我的输出必须是 8x200 的矩阵。
对于示例,我创建了两个随机数组。下面是我正在使用的基本代码:
nz=200
lev=1:nz
indices=8
var0=array(rnorm(256*256*nz),dim=c(256,256,nz))
#octo=array(sample(1:indices),dim=c(256,256,nz))
octo=array(sample(1:indices,size=256*256*nz,replace=T),dim=c(256,256,nz))
counts=apply(octo,3,function(x) table(factor(x,levels=1:indices)))
#thr=0.1
thr=0.125
np=length(var0[,1,1])*length(var0[1,,1])
profile=array(NA,dim=c(nz,indices))
t0=proc.time()
for (i in 1:indices)
{
for (z in 1:length(lev))
{
if (counts[i,z]/np>thr)
{v0=var0[,,z]; profile[z,i]=counts[i,z]/np*mean(v0[octo[,,z]==i],na.rm=T)}
}
}
print(proc.time()-t0)
user system elapsed
5.169 0.001 5.170
我尝试使用 apply 系列函数,但我无法以合理有效的方式将其写下来,因为我需要每次计算都考虑一个改变其级别的“动态”变量(即 octo 和 counts 变量)。我的真实案例是通过更大的矩阵制作的,这应该在几十个领域完成,因此时间非常重要。 您知道任何更快的替代方案吗? 非常感谢您的帮助!
编辑:我更正了 octo 的原始定义并调整了阈值 thr。这样,if 条件就有意义了,因为它并不总是得到尊重。
【问题讨论】:
-
你考虑过融化数据吗?如果你真的有动态值,也许一个整洁的结构会让它更干净。
-
另外,计数不只是一个 8192 重复的 8x200 矩阵吗? octo 的定义/计数的定义是否正确?
-
@shape 是……我也觉得很奇怪……
-
@shape 感谢您的 cmets!是的,你完全正确,octo 定义不明确,但它的定义只是一个测试用例,可以用作快速示例。