Ошибка при выполнении билинейной интерполяции с помощью `interp2 {pracma}`; Есть ли лучший способ для 2D-интерполяции?

Я пытаюсь выполнить 2D-интерполяцию для таблицы с именем vol_coarse,

install.packages("install.load")
install.load::load_package("pracma", "data.table")

vol_coarse <- data.table(V1 = c(3 / 8, 1 / 2, 3 / 4, 1, 1 + 1 / 2, 2, 3, 6),
V2 = c(0.50, 0.59, 0.66, 0.71, 0.75, 0.78, 0.82, 0.87),
V3 = c(0.48, 0.57, 0.64, 0.69, 0.73, 0.76, 0.80, 0.85),
V4 = c(0.44, 0.53, 0.60, 0.65, 0.69, 0.72, 0.76, 0.81))
setnames(vol_coarse, c("Maximum size of aggregate (in)", "2.40", "2.60", "2.80"))

x <- vol_coarse[, 2][[1]]

y <- as.numeric(colnames(vol_coarse[, 2:ncol(vol_coarse)]))

z <- meshgrid(x, y)

xp <- 3 / 4

yp <- 2.70

interp2(x = x, y = y, Z = z, xp = xp, yp = yp, method = "linear")

Это сообщение об ошибке, которое возвращается:

Ошибка: is.numeric(Z) не TRUE

Я читаю в ?interp2 тот:

length(x) = nrow(Z) = 8 and length(y) = ncol(Z) = 3 must be satisfied.

Как я могу создать матрицу 8 на 3, чтобы я мог использовать interp2?

Или есть лучший способ выполнить этот тип интерполяции?

Спасибо.

1 ответ

Решение

Если я не ошибаюсь, вы хотите:

x <- c(3 / 8, 1 / 2, 3 / 4, 1, 1 + 1 / 2, 2, 3, 6)  ## V1
y <- c(2.4, 2.6, 2.8)  ## column names
Z <- cbind(c(0.50, 0.59, 0.66, 0.71, 0.75, 0.78, 0.82, 0.87),  ## V2
           c(0.48, 0.57, 0.64, 0.69, 0.73, 0.76, 0.80, 0.85),  ## V3
           c(0.44, 0.53, 0.60, 0.65, 0.69, 0.72, 0.76, 0.81))  ## V4
xp <- 3 / 4
yp <- 2.70

У вас уже есть четко определенная матрица на сетке. Например, вы можете исследовать ваши 3D данные:

persp(x, y, Z)
image(x, y, Z)
contour(x, y, Z)

Я не рекомендую pracma как interp2 функция имеет ошибку. Я предлагаю interp.surface функция от fields пакет для интерполяции по сетке.

library(fields)
## the list MUST has name `x`, `y`, `x`!
## i.e., unnamed list `list(x, y, Z)` does not work!
interp.surface(list(x = x, y = y, z = Z), cbind(xp, yp))
# [1] 0.62

interp2 от pracma противоречиво Руководство говорит Z матрица length(x) от length(y), но функция действительно проверяет, что Z должно быть length(y) от length(x),

## from manual

   Z: numeric ‘length(x)’-by-‘length(y)’ matrix.

## from source code of `interp2`

   lx <- length(x)
   ly <- length(y)
   if (ncol(Z) != lx || nrow(Z) != ly) 
       stop("Required: 'length(x) = ncol(Z)' and 'length(y) = nrow(Z)'.")

Итак, чтобы сделать interp2 работает, ты должен пройти в транспонировании Z:

interp2(x, y, t(Z), xp, yp)
# [1] 0.62

или наоборот x а также y (а также xp, yp, тоже!!):

interp2(y, x, Z, yp, xp)
# [1] 0.62

Это действительно несовместимо с тем, как мы работаем с image, contour а также persp,

Другие вопросы по тегам