用lowess平滑

时间:2011-10-12 21:00:42

标签: r matlab smoothing

我正在尝试将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个切片执行此操作。然后,我想用跨度spanT在Dim 2中平滑,并为所有Ne切片做到这一点。

我已经看过R中的lowess函数,但看起来它有两个维度:lowess(x,y,span,iter,delta)。因此,要在R中得到上面代码的结果,我只需要为y得到一个矩阵切片并为x复制一个常量值吗?

2 个答案:

答案 0 :(得分:1)

我的Matlab非常生疏,但如果我理解正确,您可能希望将1:Ne参数的序列1:4000x传递给lowess ,因为这是你平滑点的x坐标。这假设你假设你的分数确实是等距的。

这样的事情会起作用:

#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.smoothloess使用公式界面,因此您需要直接致电loess.smooth。但它的默认值与lowess不同,所以要小心。交换该功能将我的运行时间缩短了近1/4。

答案 1 :(得分: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        
}

我想提一下,其中一个关键是在第一次平滑时设置evaluate = Ne,否则结果为null。我不知道为什么会这样,但也许是因为数据稀少而且非常不连续。