我正在尝试将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复制一个常量值吗?
答案 0 :(得分:1)
我的Matlab非常生疏,但如果我理解正确,您可能希望将1:Ne
参数的序列1:4000
或x
传递给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.smooth
。 loess
使用公式界面,因此您需要直接致电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。我不知道为什么会这样,但也许是因为数据稀少而且非常不连续。