Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R:为什么不是';这个矩阵3d线性插值工作正常吗?_R_Matrix_Interpolation_Linear Interpolation - Fatal编程技术网

R:为什么不是';这个矩阵3d线性插值工作正常吗?

R:为什么不是';这个矩阵3d线性插值工作正常吗?,r,matrix,interpolation,linear-interpolation,R,Matrix,Interpolation,Linear Interpolation,我有一个值和零的矩阵,其中零=NA。这些值散布在矩阵周围,我想做的是插值所有NA值的值。以下是数据: 我试图通过获取矩阵中的所有已知值并将该值乘以距离来猜测所有这些值(例如,点越远,其影响越小)。这是插值结果的样子: 如您所见,此方法不是非常有效,它确实会影响最接近已知值的NAs,但随后它们会迅速收敛到平均值。我认为这是因为它占据了整个范围,有很多起伏。。。而不仅仅是离它最近的点 显然,矩阵运算不是我的专长。。。要正确执行线性插值,我需要更改什么 代码如下: library(dplyr) l

我有一个值和零的矩阵,其中零=
NA
。这些值散布在矩阵周围,我想做的是插值所有
NA
值的值。以下是数据:

我试图通过获取矩阵中的所有已知值并将该值乘以距离来猜测所有这些值(例如,点越远,其影响越小)。这是插值结果的样子:

如您所见,此方法不是非常有效,它确实会影响最接近已知值的
NA
s,但随后它们会迅速收敛到平均值。我认为这是因为它占据了整个范围,有很多起伏。。。而不仅仅是离它最近的点

显然,矩阵运算不是我的专长。。。要正确执行线性插值,我需要更改什么

代码如下:

library(dplyr)
library(plotly)

Cont <- structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 1816, 2320, 1406, 2028, 1760, 1932, 1630, 
                    1835, 1873, 1474, 1671, 2073, 1347, 2131, 2038, 1969, 2036, 1602, 
                    1986, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 2311, 1947, 2094, 1947, 2441, 1775, 1461, 1260, 
                    1494, 2022, 1863, 1587, 2082, 1567, 1770, 2065, 1404, 1809, 1972, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                    0, 0, 0, 2314, 1595, 2065, 1870, 2178, 1410, 1994, 1979, 2111, 
                    1531, 1917, 1559, 2109, 1921, 1606, 1469, 1601, 1771, 1771), .Dim = c(19L, 
                                                                                       30L))

  ## First get real control values
  idx <- which(Cont > 0, arr.ind=TRUE)
  V <- Cont[idx]
  ControlValues <- data.frame(idx,V)

  ## Make data.frame of values to fill
  toFill <- which(Cont == 0, arr.ind=TRUE) %>% as.data.frame
  toFill$V <- 0

  ## And now figure out the weighted value of each point
  for (i in 1:nrow(toFill)){
    toFill[i,] -> CurrentPoint

    Xs <- (1/abs(CurrentPoint[,1] - ControlValues[,1])) 
    Xs[is.infinite(Xs)] <- 0
    Xs <- Xs/sum(Xs)/100

    Ys <- (1/abs(CurrentPoint[,2] - ControlValues[,2])) 
    Ys[is.infinite(Ys)] <- 0
    Ys <- Ys/sum(Ys)/100

    ControlValues1 <- data.frame(Xs,Ys)
    toFill[i,3] <- sum(rowMeans(ControlValues1) * ControlValues$V)*100
  }

  ## add back in the controls and reorder
  bind_rows(ControlValues,toFill) -> Both
  Both %>% arrange(row,col) -> Both

  ## and plot the new surface
  NewCont <- matrix(Both$V,max(Both$row),max(Both$col),byrow = T)
  plot_ly(z=NewCont, type="surface",showscale=FALSE) 
库(dplyr)
图书馆(绘本)

ContR中插值和外推数据的一种方法是使用
akima
包。以下执行双线性插值,然后使用数据帧
控制值
中的已知数据点作为输入进行外推,以填充
控制中的零

library(akima)
library(plotly)

NewCont <- akima::interp(x=ControlValues[,1], y=ControlValues[,2], z=ControlValues[,3],
                         xo=1:nrow(Cont), yo=1:ncol(Cont), linear=TRUE)$z
NewCont[,1:9] <- akima::interp.old(x=ControlValues[,1], y=ControlValues[,2], 
                                   z=ControlValues[,3], xo=1:nrow(Cont), 
                                   yo=1:9, ncp=2, extrap=TRUE)$z

plot_ly(z=NewCont, type="surface",showscale=FALSE)
这里的要求与
akima::interp
的要求相反。具体而言,已知数据点必须位于
x-y
网格上。然而,要插值的坐标不需要在网格上,而是包含
x
y
坐标对应列向量的矩阵,其中每个元组
(x[i],y[i])
是要插值的
x-y
坐标。由于
ControlValues
中的数据点位于网格上,因此这种情况下也满足这些要求。有关用法和详细信息,请参阅帮助页
?interp.surface

注:

  • sort(unique(ControlValues[,1]))
    sort(unique(ControlValues[,2])
    仅给出已知数据点网格的
    x
    y
    坐标
  • 列表中的
    z
    组件仅仅是已知数据点的
    z
    值,这些数据点被重塑为已知数据点网格上的矩阵
  • 要插值的坐标矩阵由
    make.surface.grid
    生成,使用as
    x
    y
    分别协调
    Conf
    的行和列索引
  • 位于已知点网格之外的要插值的坐标将产生
    NA
  • interp.surface
    返回与要插值的坐标相对应的
    z
    值向量。然后将其重新调整为坐标网格上的矩阵进行插值,该矩阵具有
    nrow(Cont)
    by
    ncol(Cont)
  • 最后,很容易验证这两种方法给出相同的结果

    print(max(abs(NewCont - NewCont2)))
    ##[1] 4.547474e-13
    

    您将无法插值
    x<10
    的值,因为您的数据不受支持。如果您只对范围
    10的插值感兴趣,则为公平点。我想进行内插和外推。我做的不是双线性插值吗?我不认为你的代码做双线性插值。另外,请注意,由于您的数据非常稀少,因此在您的情况下,外推没有什么价值。我非常希望看到一个工作示例,正如我提到的,矩阵运算不是我的强项。谢谢回答得很好。我甚至想问一下如何比较插值方法,但很高兴你在最后展示了这一点。精彩的!难以置信这两种方法如此接近。。。我想插值算法很相似吧?我注意到的另一件事,有点恼人的是,山峰和山谷都太极端了。。。如果我对构建基线控制曲面感兴趣,也许我应该先应用一些平滑处理。有什么正确的方法吗?或者将我所有的值乘以
    0.8左右是公平的吗?再次感谢@AmitKohli很抱歉延迟回复您。对于第一个问题,简短的回答是,
    akima
    中的算法更复杂,因为它不需要已知点的网格进行插值。然而,
    字段
    中的算法通常被称为双线性插值。这需要一个已知点的网格,您的数据恰好满足该网格。关于第二个问题的答案,请参阅我的下一条评论。@AmitKohli正确的方法取决于数据的含义。如果已知您的数据非常准确,那么您应该进行插值(并且可以进行外推)。要获得额外的平滑度,可能需要使用高阶函数(如三次样条曲线)进行插值。如果已知数据有噪声,则需要将某些函数拟合到这些数据点,以最小化某些错误标准。这是估计。这里,函数可以是线性的,也可以是高阶的。不同之处在于拟合通常不会保留由估计函数表示的数据值。这正是我正在寻找的帮助。我可以告诉你更多关于这个项目的信息。。。我正试图帮助我的父亲(一位小麦育种家)使用一种更好的方法来解释试验小麦产量相对于散布在整个田地中的对照品种。你愿意合作吗?我不知道您是否参与了开发,但对于真正需要它的人来说,这可能是一个非常有用的工具!我很想听听你对真实数据的看法。有兴趣做你该做的吗?:)
    print(max(abs(NewCont - NewCont2)))
    ##[1] 4.547474e-13