【发布时间】:2018-01-26 17:59:46
【问题描述】:
我需要确定由离散数据点表示的一系列表面下方的体积。在我的数据中,每个样本都存储为数据框列表中的单独数据框。这是一些(小)示例数据:
df1 <- data.frame(x=c(2,2,2,3,3,3,4,4,4,5,5,5,6,6,6),
y=c(1,2,3,1,2,3,1,2,3,1,2,3,1,2,3),
z=c(0,2,0,4,6,7,3,2,1,2,7,8,9,4,2))
df2 <- data.frame(x=c(2,2,2,3,3,3,4,4,4,5,5,5,6,6,6),
y=c(1,2,3,1,2,3,1,2,3,1,2,3,1,2,3),
z=c(1,1,2,3,5,6,2,1,3,3,8,9,8,3,1))
DF <- list(df1,df2)
类似问题的答案要么使用其他语言(matlab、python),要么答案不包含解决问题的可用脚本(as here)。我可以想到两种可接受的方法来估计每个表面下的体积:1)写出辛普森规则的离散版本,作为 R 中的一个函数,应用于数据帧列表(DF); 2) 计算 x、y 和 z 之间的任意关系,并使用多元数值积分来找到表面下的体积(使用 pracma 包中的 simpson2d / quad2d 或 cubature 中的 adaptIntegrate 等函数)。
关于第一种方法,复合辛普森规则的公式(我想使用)是here,但由于其复杂性,我未能成功编写一个有效的双重求和函数。在这个表达式中,I(lambda(em) lambda(ex)) 等于上述数据集中每个 x,y 网格点的 z,Delta(em) 和 Delta(ex) 表示 x 和 y 点之间的间隔。
第二种方法本质上将found here 方法扩展为多元样条拟合,然后将预测的 z 值作为积分函数传递。以下是我迄今为止尝试过的这种方法:
require(pracma)
df1.loess <- loess(z ~ x + y, data=DF[[1]])
mod.fun <- function(x,y) predict(df1.loess, newdata=x,y)
simpson2d(mod.fun, x=c(2,6), y=c(1,3))
但这不会产生有用的结果。
实际上,我有一个包含近 100 个单个样本的数据帧的列表,因此我确实需要能够将解决方案表示为一系列 lapply 函数,这些函数可以跨列表中的所有数据帧自动执行这些计算。一个示例如下所示:
require(akima)
DF.splines <- lapply(DF, function(x,y,z) interp(x = "x", y = "y", z = "z",
linear=F, nx=4, ny=2))
不幸的是,这会产生缺失值和 Inf 的异常。对于如何成功实施这些策略之一或使用不同(更简单?)方法的任何建议,我都非常愿意接受。克里金函数(如 DiceKriging 包中的 km)能否产生更好的拟合,可以传递给数值积分?
【问题讨论】:
-
你的形状是凸的吗?
-
是的,每个数据框都描述了一个矩形区域,x 和 y 坐标之间的间隔是偶数。我正在寻找 z 值的随机波动表面下方的区域。这些区域应该是凸的。
-
哦,我没有看到 x,y 网格是规则的。凸的意味着对于你从你的体积中取的任何两个点,连接这两个点的直线上的所有点都在体积内。因此,如果 z 值是任意的,则体积很可能不是凸的。
标签: r interpolation spline numerical-integration