为什么akima :: interp插值在原始数据的边界之外? - R.

时间:2017-07-04 16:28:05

标签: r interpolation tidyverse

如果我使用quakes数据集而tidyverse使用akima包绘制插值,我试图这样做:

library(tidyverse)
library(akima)

插值函数:

## Interpolation and convert to a dataframe
dpinterp <- function(x,y,z) {
  interp_df <- interp(x = x, y = y, z = z, duplicate = "strip", extrap = FALSE, nx = 100, ny = 100)
  interp2xyz(interp_df, data.frame=TRUE)
}

找出每个stations变量的最大深度。选择小于34的stations子集以便于分析:

quakes_sub <- quakes %>%
  filter(stations <= 34) %>%
  group_by(stations) %>%
  summarise(depth = max(depth)) %>%
  mutate(mag = 4)

管道完成插值然后一些数据清理/争吵:

quakes_interp <- quakes %>%
  filter(stations <= 34) %>%
  do(dpinterp(x = .$stations, y = .$depth, z = .$mag)) %>%
  filter(!is.na(z)) %>%
  rename(stations = x, depth = y, mag = z) 

可视化图并说明插值如何超出原始数据点。蓝点:

quakes_interp %>%
  ggplot(aes(x = stations, y = depth, z = mag, fill = mag)) + 
  geom_tile() + 
  scale_y_reverse(expand = c(0,0)) +
  scale_x_continuous(expand = c(0, 0)) +
  #geom_vline(data = quakes_sub, aes(xintercept = stations, colour= depth)) +
  geom_point(data = quakes_sub, aes(x = stations, y = depth, colour = mag)) +
  #stat_contour(aes(fill=..level..), geom="polygon", binwidth=0.005) + 
  #geom_contour(color = "white", alpha = 0.5) + 
  #geom_text(data = meta_data, aes(label = Station)) +
  scale_fill_distiller(palette="RdYlGn", 
                       na.value="white") + 
  theme_minimal() 

enter image description here

问题:有没有办法约束插值,使其不超出原始原始数据?

会话信息

R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_Canada.1252  LC_CTYPE=English_Canada.1252    LC_MONETARY=English_Canada.1252
[4] LC_NUMERIC=C                    LC_TIME=English_Canada.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] bindrcpp_0.2       padr_0.3.0         lubridate_1.6.0    akima_0.6-2        readxl_1.0.0       dplyr_0.7.1       
 [7] purrr_0.2.2.2      readr_1.1.1        tidyr_0.6.3        tibble_1.3.3       ggplot2_2.2.1.9000 tidyverse_1.1.1   

loaded via a namespace (and not attached):
 [1] reshape2_1.4.2     haven_1.0.0        lattice_0.20-35    colorspace_1.3-2   htmltools_0.3.6    yaml_2.1.14       
 [7] rlang_0.1.1        foreign_0.8-67     glue_1.1.1         RColorBrewer_1.1-2 sp_1.2-4           modelr_0.1.0      
[13] fortunes_1.5-4     bindr_0.1          plyr_1.8.4         stringr_1.2.0      munsell_0.4.3      gtable_0.2.0      
[19] cellranger_1.1.0   rvest_0.3.2        psych_1.7.5        evaluate_0.10      labeling_0.3       knitr_1.16        
[25] forcats_0.2.0      parallel_3.4.0     broom_0.4.2        Rcpp_0.12.11       scales_0.4.1       backports_1.1.0   
[31] jsonlite_1.5       mnormt_1.5-5       hms_0.3            digest_0.6.12      stringi_1.1.5      grid_3.4.0        
[37] rprojroot_1.2      tools_3.4.0        magrittr_1.5       lazyeval_0.2.0     pkgconfig_2.0.1    swtext_0.0.1      
[43] xml2_1.1.1         assertthat_0.2.0   rmarkdown_1.6      httr_1.2.1         R6_2.2.1           nlme_3.1-131      
[49] compiler_3.4.0    

1 个答案:

答案 0 :(得分:1)

您插入的数据来自quakesstations小于或等于34:

quakes_interp <- quakes %>%
  filter(stations <= 34) %>%
  do(dpinterp(x = .$stations, y = .$depth, z = .$mag))

让我们解读一下:

> qdata = quakes %>% filter(stations <=34)

现在让我们绘制interp已插入的位置:

> plot(quakes_interp$stations, quakes_interp$depth)

现在在顶部添加数据点:

> points(qdata$stations,qdata$depth,col="red",pch=19)

为了获得良好的衡量标准,请添加原始数据点的凸包:

> lines(
    qdata[
        chull(qdata$stations, qdata$depth),
        c("stations","depth")],lwd=2)

enter image description here

(与你的相比颠倒)

您的问题是“有没有办法约束插值,使其不会超出原始原始数据?”我似乎已经证明它,其中“beyond”的定义是凸包。

如果你为每个电台单独interp,那么interp不会超出depth的最小值和最大值,因为你会有一维情况(mag~深度)和一维中的凸包由尺寸的最小值和最大值定义。

interp用于在连续坐标上进行插值。您认为它不应超出每个站的最大(深度)不适用。对interp的眼睛来说,站是一个连续的坐标,就像空间中的坐标一样。在大多数使用连续坐标的情况下,任何max(x)的{​​{1}}将是与y一致的x的一个值,因为y,连续的,只有独特的价值。

凸包是对“这组坐标点的感兴趣区域是什么?”问题的一个答案。其他答案可能是“矩形边界框[min(x),max(x),min(y),max(y)]”或“由alpha = 0.2定义的凹形船体α形状”,或“海岸线的法国”。如果您想限制您的感兴趣区域,只能扩展到每个工作站的最大(深度),那么您需要手动剪切y的输出。

interp在这里可能完全不合适 - 如果interp在整数上是离散的,那么stations处的插值值可能毫无意义。

实际上,stations==3.75甚至可能是wronger。它基于坐标的相等性进行插值,使得1个站的差异与1个深度单位的差异相同。这解释了绘图中水平条纹的外观。如果您通过将interp添加到coord_equal()来执行宽高比为1的绘图,则会看到ggplot正在使用的实际2d曲面。