Интерполировать между каждой строкой data.frame

Я хочу быстро выполнить повторную выборку 9X_interpolate и интерполяцию между каждой строкой data.frame. Я 9X_base-r не возражаю против работы с data.table или другими 9X_interpolation структурами данных, если это необходимо. Вот 9X_base-r воспроизводимый пример:

df <- data.frame(x = c(0, 2, 10), y = c(10, 12, 0)) 

Желаемый результат: функция 9X_interpolation f(df, n), где n — количество значений интерполяции, которые 9X_base-r приведут к:

df_int <- f(df, 1) # That would produce : # df_int <- data.frame(x = c(0, 1, 2, 6, 10), # y = c(10, 11, 12, 6, 0)) df_int <- f(df, 3) # That would produce : # df_int <- data.frame(x = c(0, 0.5, 1, 1.5, 2, 4, 6, 8, 10), # y = c(10, 10.5, 11, 11.5, 12, 9, 6, 3, 0)) 

Некоторые решения были предложены 9X_interpolation с использованием approx, но в моем случае это 9X_r-language не работает.

8
0
3
Общее количество ответов: 3

Ответ #1

Ответ на вопрос: Интерполировать между каждой строкой data.frame

Без учета скорости

interpolate_vector <- function(x, n) { Reduce(function(x, tail_x) { c(head(x, -1), seq(tail(x, 1), tail_x[1], length.out = n + 2)) }, init = x[1], x = tail(x, -1)) } f <- function(df, n) { as.data.frame(lapply(df, interpolate_vector, n)) } 
f(df, 1) 
 x y 1 0 10 2 1 11 3 2 12 4 6 6 5 10 0 
f(df, 3) 
 x y 1 0.0 10.0 2 0.5 10.5 3 1.0 11.0 4 1.5 11.5 5 2.0 12.0 6 4.0 9.0 7 6.0 6.0 8 8.0 3.0 9 10.0 0.0 

Без Reduce и растущих векторов:

interpolate_vector_2 <- function(x, n) { res <- numeric(length = (length(x)-1) * (n+1) + 1) for (i in head(seq_along(x), -1)) { res[(i + (i-1)*n) : (i + i*n + 1)] <- seq(x[i], x[i+1], length.out = n+2) } res } f_2 <- function(df, n) { as.data.frame(lapply(df, interpolate_vector_2, n)) } 

Шаблон 9X_base-r эталона (включая ответы @Maël):

res <- bench::press( rows = c(1e2, 1e3), n = c(1, 3, 10), { df <- data.frame( x = runif(rows), y = runif(rows) ) bench::mark( zoo = f_3(df, n), loop = f_2(df, n), reduce = f(df, n), approx = f_4(df, n) ) } ) 

9X_Интерполировать между каждой строкой data.frame_interpolation

11
0

Ответ #2

Ответ на вопрос: Интерполировать между каждой строкой data.frame

Другая возможность с zoo::na.approx. Идея состоит в том, чтобы 9X_interpolation создать вектор с n NA между элементами векторов, а 9X_rstats затем использовать na.approx. Это решение предположительно 9X_rstats является самым быстрым (см. benchmark).

library(zoo) interp <- function(v, n){ na_vec <- c(sapply(v, \(x) c(x, rep(NA, n))))[1:((length(v) - 1) * (n + 1) + 1)] zoo::na.approx(na_vec) } f <- function(df, n) as.data.frame(lapply(df, interp, n)) 

примеры

f(df, 1) # x y # 1 0 10 # 2 1 11 # 3 2 12 # 4 6 6 # 5 10 0 f(df, 3) # x y # 1 0.0 10.0 # 2 0.5 10.5 # 3 1.0 11.0 # 4 1.5 11.5 # 5 2.0 12.0 # 6 4.0 9.0 # 7 6.0 6.0 # 8 8.0 3.0 # 9 10.0 0.0 

6
0

Ответ #3

Ответ на вопрос: Интерполировать между каждой строкой data.frame

Использование approx:

interp <- function(x, n){ v = c() for(i in seq(length(x) - 1)) { tmp = approx(c(x[i], x[i + 1]), n = 2 + n)$y v = c(v, tmp) } v[!duplicated(v)] } f <- function(df, n) as.data.frame(lapply(df, interp, n)) 

примеры

f(df, 1) # x y # 1 0 10 # 2 1 11 # 3 2 12 # 4 6 6 # 5 10 0 f(df, 3) # x y # 1 0.0 10.0 # 2 0.5 10.5 # 3 1.0 11.0 # 4 1.5 11.5 # 5 2.0 12.0 # 6 4.0 9.0 # 7 6.0 6.0 # 8 8.0 3.0 # 9 10.0 0.0 

9X_rstats

4
0