我有一系列地形剖面扫描,我想组合起来创建一个连续的剖面图。唯一的问题是每次扫描可能是也可能没有从不同的高度拍摄,因此虽然不同的文件在所覆盖的区域方面具有相当多的重叠,但是不同的数据可能没有共同的参考点。绝对高度。
以下是4种不同的扫描结果。每次扫描包含大约30次测量,最后几次测量代表新数据,其余测量与前一次扫描重叠。第一次扫描包含唯一已知的绝对值,因此第一次扫描是"黄金标准"。第二次扫描恰好取自相同的高度,因此重叠匹配(几乎)完美,并且仅向前一次扫描添加4个新点。第三次和第四次扫描取自不同的高度,因此虽然重叠覆盖相同的区域(相对),但我不能简单地将其缝合到前两次扫描上。
Scan1<-c(5,6,7,8,15,16,18,20,25,23,20,17,15,10,10,9,8,9,11,10,13,16,17,19,20,25,28,30,29,30)
Scan2<-c(15,16,18,20,25,23,20,16,15,10,10,9,8,9,11,10,13,16,17,19,20,25,28,30,29,30,32,35,38,37)
Scan3<-c(28,25,23,18,18,17,16,17,19,18,21,23,25,27,26,33,36,37,37,38,40,43,46,45,43,42,40,38,32,30)
Scan4<-c(27,30,29,36,39,39,40,41,43,46,49,48,46,45,43,41,35,33,30,29,28,30,31,32,35)
使用R,有没有办法将这4个扫描拼接在一起以形成连续的地形轮廓?绝对高度需要基于第一次扫描,每次连续扫描都被缝合到先前的扫描上。将IE-Scan2拼接到扫描1上,添加4个数据点,然后将来自扫描3的新数据添加到Scan1和Scan2的组合中,然后将来自Scan4的新数据添加到扫描1,2和3的组合中等等....
我假设有一种方法可以通过匹配扫描之间的大重叠来标准化所有数据,使用某种模式识别来确定Scan3与Scan1大约有8个单位,而Scan4是约11个单位。但请注意,有一些&#34;噪音&#34;在我的数据和重叠的模式将不是一个完美的契合。
最终结果应包含完整的地形轮廓,包含所有4次扫描,并对实际数字的差异进行某种调整。有点像:
5,6,7,8,15,16,18,20,25,23,20,16.5,15,10,10,9,8,9,11,10,13,15.5,17,19,19,25,28,29.5,29,30,32,35,38,37,35,34,32,30,24,22,19,18,17,19,20,21,24
答案 0 :(得分:1)
你可能想要研究序列比对 - DNA比对基本上是这个问题,但是有了碱基而不是数字。
作为一个快速结束,这是一个快速写作功能,以找到最好的&#34;移动,基于在滑动扫描时找到值之间的差的最低标准偏差。该函数采用给定的两个序列,并将它们与给定的移位(默认为-15到15)进行比较:
aligner <- function(bestsequence, sequence2, shift = (-15):15){
minsd <- sd(bestsequence[1:min(length(sequence2), length(bestsequence))] - sequence2[1:min(length(sequence2), length(bestsequence))])
bestshift <- 0
avgdiff <- mean(bestsequence[1:min(length(sequence2), length(bestsequence))] - sequence2[1:min(length(sequence2), length(bestsequence))])
for(i in shift){
if(i < 0){
worksequence2 <- sequence2[abs(i):length(sequence2)]
if(sd(bestsequence[1:min(length(worksequence2), length(bestsequence))]
- worksequence2[1:min(length(worksequence2), length(bestsequence))]) < minsd){
minsd <- sd(bestsequence[1:min(length(worksequence2), length(bestsequence))]-
worksequence2[1:min(length(worksequence2), length(bestsequence))])
bestshift <- i
avgdiff <- mean(bestsequence[1:min(length(worksequence2), length(bestsequence))]-
worksequence2[1:min(length(worksequence2), length(bestsequence))])
}
}
if(i > 0){
workbest <- bestsequence[i:length(bestsequence)]
if(sd(workbest[1:min(length(sequence2), length(workbest))]
-sequence2[1:min(length(sequence2), length(workbest))]) < minsd){
minsd <- sd(workbest[1:min(length(sequence2), length(workbest))]-
sequence2[1:min(length(sequence2), length(workbest))])
bestshift <- i
avgdiff <- mean(workbest[1:min(length(sequence2), length(workbest))]-
sequence2[1:min(length(sequence2), length(workbest))])
}
}
}
return(list(bestshift = bestshift, avgdiff = avgdiff, minsd = minsd))
}
所以,对于你的数据:
aligner(Scan1, Scan2)
$bestshift
[1] 5
$avgdiff
[1] 0.03846154
$minsd
[1] 0.1961161
因此,您的Scan2s 5th元素等于Scan1的第一个元素。从这里开始,应该很容易通过avgdiff进行子集化,修正并附加新的数据点,然后重新运行。
编辑:这里是如何获得最终序列的。首先,我们需要一个输出所需序列的包装器。它基本上运行上一个命令,然后检查移位是正还是负,然后输出正确的序列:
wrappedaligner <- function(bestseq, seq2){
z <- aligner(bestseq, seq2)
if(z$bestshift==0){
if(length(bestseq) >= length(seq2)){
return(bestseq)
} else {return(c(bestseq, (seq2[(length(bestseq)+1):length(seq2)])-z$avgdiff))}
}
else if(z$bestshift > 0){
if(length(bestseq)-z$bestshift >= length(seq2)){
return(bestseq)
} else {return(c(bestseq, seq2[(length(bestseq) - z$bestshift + 2):length(seq2)] - z$avgdiff))}
}
else if(z$bestshift <0){
if((length(bestseq) - abs(z$bestshift))>= length(seq2)){
return(bestseq)
} else {return(c(seq2[1:abs(z$bestshift) - 1] - z$avgdiff, bestseq))}
}
}
现在我们需要以递归方式运行您的数据 - 幸运的是我们可以使用Reduce
:
Reduce(wrappedaligner, list(Scan1, Scan2, Scan3, Scan4))
[1] 5.00000 6.00000 7.00000 8.00000 15.00000 16.00000 18.00000 20.00000
[9] 25.00000 23.00000 20.00000 17.00000 15.00000 10.00000 10.00000 9.00000
[17] 8.00000 9.00000 11.00000 10.00000 13.00000 16.00000 17.00000 19.00000
[25] 20.00000 25.00000 28.00000 30.00000 29.00000 30.00000 31.96154 34.96154
[33] 37.96154 36.96154 50.83974 49.83974 47.83974 45.83974 39.83974 37.83974