1

我正在尝试将 matlab 脚本转换为 R,并且在平滑时遇到了一些问题。

我要转换的matlab代码如下:

for i = 1:size(spike_sum,2)
        smooth_sum(1:Ne,i)=smooth(double(spike_sum(1:Ne,i)),spanNe,'lowess');
end

for i = 1:Ne
        smoother_sum(i,:)=smooth(double(smooth_sum(i,:)),spanT,'lowess');
end

其中spike_sum是一个Ne x 4000的矩阵。我想首先在Dim 1中进行平滑,使用span spanNe,并对所有4000个切片执行此操作。然后,我想在 Dim 2 中使用 span spanT 进行平滑处理,并对所有 Ne 切片执行此操作。

我已经查看了 R 中的 lowess 函数,但它似乎需要二维作为 lowess(x,y,span,iter,delta)。因此,要在 R 中获得上述代码的结果,我是否只需为 y 取一个矩阵切片并为 x 复制一个常量值?

4

2 回答 2

1

我的 Matlab 很生锈,但如果我理解正确,您可能希望将序列1:Ne或参数传递给1:4000,因为这意味着您正在平滑的点的 x 坐标。这假设您假设您的点确实是等距的。xlowess

像这样的东西会起作用:

#Example matrix
M <- matrix(runif(1600),40,40)

#Smooth rows; transpose when smoothing over rows
M1 <- t(apply(M,1,FUN = function(x){lowess(1:length(x),x)$y}))

#Smooth columns; but don't transpose; fills by column already
M2 <- apply(M1,2,FUN = function(x){lowess(1:length(x),x)$y})

我没有包括不同的跨度,但你可以自己添加这些细节。

编辑

啊,但是如果您正在寻找速度,您可能应该loess.smooth直接使用。loess使用公式接口,因此您需要loess.smooth直接调用。但是,它的默认值与 不同lowess,所以要小心。交换该功能将我的运行时间缩短了近 1/4。

于 2011-10-12T21:10:57.050 回答
0

好吧,尽管 joran 提供的答案没有按预期工作,并且 joran 花了很多时间尝试调试它,我很感激,但最终我无法让该解决方案正常工作,我真的不知道为什么,但它没有产生与 matlab 代码相当的结果。在搞砸之后,我发现了这个解决方案(这可能不是最佳的,但可以按预期工作)

loesscontrol=loess.control(surface="interpolate", statistics="approximate", trace.hat="exact", iterations=1)
spanNe=100/Ne
spanT=50/nsteps
spanNi=30/Ni

for (i in 1:nsteps){
        x<-1:Ne
        y<-spike_sum[1:Ne,i]
        smoothingNe<-loess.smooth(x, y, span=spanNe, degree=1, family="gaussian", evaluation=Ne)
        smooth_sumNe[1:Ne,i]<-smoothingNe$y
}

for (i in 1:Ne){
        x<-1:nsteps
        y<-smooth_sumNe[i,1:nsteps]
        smoothingT<-loess.smooth(x, y, span=spanT, degree=1, control=loesscontrol, family="gaussian", evaluation=nsteps)
        smoother_sumNe[i,1:nsteps]<-smoothingT$y        
}

我想提一下,这里的一个关键是在第一次平滑时设置evaluation=Ne,否则结果为null。我不知道为什么会这样,但可能是因为数据稀疏且高度不连续。

于 2011-10-13T17:49:02.627 回答