Nothing
## Test compute_local_windows() =========================================
test_that("compute_local_windows returns correct structure", {
t <- 1:10
width <- 3
result <- compute_local_windows(t, width = width, span = NULL)
expect_type(result, "list")
expect_length(result, length(t))
expect_true(all(vapply(result, is.numeric, logical(1))))
## with span
t <- seq(0, 10, by = 0.5)
span <- 1
result <- compute_local_windows(t, width = NULL, span = span)
expect_type(result, "list")
expect_length(result, length(t))
})
test_that("compute_local_windows respects width boundaries", {
t <- 1:10
width <- 3
result <- compute_local_windows(t, width = width)
# First element: can only look forward
expect_equal(result[[1]], 1:2)
# Last element: can only look backward
expect_equal(result[[10]], 9:10)
# Middle element: symmetrical window
expect_equal(result[[5]], c(4:6))
## even width align centreed
width <- 2
result <- compute_local_windows(t, width = width, align = "centre")
# left-biased forward looking
expect_equal(result[[1]], 1:2)
# Last element only at idx
expect_equal(result[[10]], 10)
# left-biased forward looking
expect_equal(result[[5]], c(5:6))
## with span
t <- seq(0, 10, by = 0.5)
span <- 2
result <- compute_local_windows(t, span = span)
# First element: can only look forward
expect_equal(result[[1]], 1:3)
expect_equal(t[result[[1]]], t[1:3])
# Last element: can only look backward
expect_equal(result[[21]], 19:21)
expect_equal(t[result[[21]]], t[19:21])
# Middle element: symmetrical window
expect_equal(result[[10]], c(8:12))
expect_equal(t[result[[10]]], t[c(8:12)])
})
test_that("compute_local_windows align = 'center'", {
t <- 1:10
width <- 2
result <- compute_local_windows(t, width = width, align = "center")
expect_equal(result[[1]], 1:2)
expect_equal(result[[10]], 10)
expect_equal(result[[5]], c(5:6))
})
test_that("compute_local_windows width and span >= length(x) works", {
t <- 1:10
result <- compute_local_windows(t, width = 20)
expect_equal(result, rep(list(t), length(t)))
result <- compute_local_windows(t, span = 20)
expect_equal(result, rep(list(t), length(t)))
})
test_that("compute_local_windows works with width = 1 and span = 0", {
t <- 1:10
result <- compute_local_windows(t, width = 1)
expect_equal(result, as.list(t))
result <- compute_local_windows(t, span = 0)
expect_equal(result, as.list(t))
compute_local_windows(t, width = 1, span = 0)
})
## test compute_valid_neighbours() ===========================
test_that("compute_valid_neighbours() works with width", {
x <- c(1, 2, NA, 4, 5, NA, 7)
# width = 1
result <- compute_valid_neighbours(x, width = 3)
expect_length(result, 2) # Two NAs
expect_equal(result[[1]], c(2, 4))
expect_equal(result[[2]], c(5, 7))
# width = 3
x <- c(1, 2, 3, NA, 5, 6, 7)
result <- compute_valid_neighbours(x, width = 4)
expect_equal(result[[1]], c(2, 3, 5, 6))
# Edge case: NA at start
x <- c(NA, 20, 30, 40)
result <- compute_valid_neighbours(x, width = 3)
expect_equal(result[[1]], 2)
# Edge case: NA at end
x <- c(10, 20, 30, NA)
result <- compute_valid_neighbours(x, width = 3)
expect_equal(result[[1]], 3)
})
test_that("compute_valid_neighbours() works with span", {
t <- 0:4
x <- c(1, 2, NA, 4, 5)
# span = 1 (includes t[2] = 1 and t[4] = 3)
result <- compute_valid_neighbours(x, t = t, span = 1)
expect_length(result, 1)
expect_equal(result[[1]], c(2, 4))
# span = 0.5 (no values of t within t ± span should return same as width = 1)
result <- compute_valid_neighbours(x, t = t, span = 0.5)
expect_equal(result[[1]], c(2, 4))
expect_equal(result, compute_valid_neighbours(x, width = 3))
# Multiple NAs
x <- c(1, NA, 3, NA, 5)
result <- compute_valid_neighbours(x, t = t, span = 1)
expect_length(result, 2)
expect_equal(result[[1]], c(1, 3))
expect_equal(result[[2]], c(3, 5))
# Edge case: NA at start
x <- c(NA, 2, 3, 4)
expect_equal(compute_valid_neighbours(x, span = 1)[[1]], 2)
expect_equal(compute_valid_neighbours(x, span = 0.5)[[1]], 2)
# Edge case: NA at end
x <- c(1, 2, 3, NA)
expect_equal(compute_valid_neighbours(x, span = 1)[[1]], 3)
expect_equal(compute_valid_neighbours(x, span = 0.5)[[1]], 3)
})
test_that("compute_valid_neighbours width and span >= length(x) works", {
x <- c(1, 2, NA, 4, 5)
result <- compute_valid_neighbours(x, width = 8)
expect_equal(result, list(x[!is.na(x)]))
result <- compute_valid_neighbours(x, span = 8)
expect_equal(result, list(x[!is.na(x)]))
})
test_that("compute_valid_neighbours works with width = 1 and span = 0", {
x <- c(1, 2, NA, 4, 5)
result <- compute_valid_neighbours(x, width = 1)
expect_equal(result[[1]], c(2, 4))
result <- compute_valid_neighbours(x, span = 0)
expect_equal(result[[1]], c(2, 4))
})
## Test compute_local_fun() =========================================
test_that("compute_local_fun returns correct length", {
x <- c(1, 2, 3, 4, 5)
window_idx <- compute_local_windows(x, width = 1)
result <- compute_local_fun(x, window_idx, fn = median)
expect_type(result, "double")
expect_length(result, length(x))
})
test_that("compute_local_fun calculates correct medians", {
x <- c(10, 20, 30, 40, 50)
# Manual windows: each looks at neighbours
window_idx <- compute_local_windows(x, width = 3)
result <- compute_local_fun(x, window_idx, fn = median)
expect_equal(result[1], median(x[1:2])) # median of x[2]
expect_equal(result[2], median(x[1:3])) # median of x[c(1,3)]
expect_equal(result[5], median(x[4:5])) # median of x[4]
})
test_that("compute_local_fun handles NA values", {
## this shouldn't happen with handle_na, but just in case
x <- c(1, NA, 3, 4, 5)
window_idx <- compute_local_windows(x, width = 3)
result <- compute_local_fun(x, window_idx, fn = median, na.rm = TRUE)
expect_false(all(is.na(result[1:3])))
expect_equal(result[1], median(x[1]))
expect_equal(result[2], median(x[c(1, 3)]))
expect_equal(result[3], median(x[c(3, 4)]))
})
test_that("compute_local_fun() handles empty windows", {
x <- c(1, 2, 3)
window_idx <- list(integer(0))
result <- compute_local_fun(x, window_idx, fn = median, na.rm = TRUE)
expect_true(is.na(result))
})
test_that("compute_local_fun() handles single values", {
x <- c(10, 20, 30)
window_idx <- list(1, 2, 3)
result <- compute_local_fun(x, window_idx, fn = median)
expect_equal(result, x)
})
## Test compute_outliers() ==============================================
test_that("compute_outliers returns list of logical and numeric vectors", {
x <- c(1, 2, 3, 100, 5)
t <- 1:5
window_idx <- compute_local_windows(t, width = 3, span = NULL)
result <- compute_outliers(x, window_idx, outlier_cutoff = 3)
expect_type(result$local_medians, "double")
expect_type(result$is_outlier, "logical")
expect_length(result$local_medians, length(x))
expect_length(result$is_outlier, length(x))
expect_true(result$is_outlier[4L]) # 100 should be flagged
expect_false(any(result$is_outlier[-4L])) # Normal values should not be flagged
})
test_that("compute_outliers threshold sensitivity via outlier_cutoff", {
x <- c(1, 2, 3, 10, 5)
t <- 1:5
window_idx <- compute_local_windows(t, width = 3, span = NULL)
# Strict threshold
strict <- compute_outliers(x, window_idx, outlier_cutoff = 1)
# Lenient threshold
lenient <- compute_outliers(x, window_idx, outlier_cutoff = 10)
expect_true(sum(strict$is_outlier) > sum(lenient$is_outlier))
expect_equal(strict$local_medians, lenient$local_medians)
})
test_that("compute_outliers handles no outliers", {
x <- 1:5
t <- 1:5
window_idx <- compute_local_windows(t, width = 3, span = NULL)
result <- compute_outliers(x, window_idx, outlier_cutoff = 3)
expect_true(all(!result$is_outlier))
})
test_that("compute_outliers handles NA", {
## this shouldn't happen with handle_na, but just in case
x <- c(1, 2, NA, 100, 5)
t <- 1:5
window_idx <- compute_local_windows(t, width = 3, span = NULL)
result <- compute_outliers(x, window_idx, outlier_cutoff = 3)
expect_true(all(!result$is_outlier))
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.