Skip to contents

[Experimental] Checks if a trajectory, defined by vectors of x and y coordinates, is monotonically increasing relative to an ideal line passing through the start and end points.

Usage

is_monotonic_along_ideal(
  x_vector,
  y_vector,
  x_start,
  y_start,
  x_end,
  y_end,
  strict = TRUE,
  warn = TRUE
)

Arguments

x_vector

x-coordinates of the executed path.

y_vector

y-coordinates of the executed path.

x_start

x-coordinate of the start point of the ideal line. Defaults to the first value in x_vector.

y_start

y-coordinate of the start point of the ideal line. Defaults to the first value in y_vector.

x_end

x-coordinate of the end point of the ideal line. Defaults to the last value in x_vector.

y_end

y-coordinate of the end point of the ideal line. Defaults to the last value in y_vector.

strict

Must the values increase strictly? Defaults to FALSE, indicating that a weak, not a strict definition of monotony is applied.

warn

Will a warning be issued if the trajectory is not monotonic (relative to the ideal line)? Defaults to TRUE.

Value

A length-one logical, indicating whether the trajectory is monotonic.

Details

Computes the orthogonal projection of the trajectory points onto the ideal line and checks whether the distances of this projection to the start point are monotonic. All objects of length 0 or 1 are monotonic. Data with missing values will not pass the check.

References

Wirth, R., Foerster, A., Kunde, W., & Pfister, R. (2020). Design choices: Empirical recommendations for designing two-dimensional finger tracking experiments. Behavior Research Methods, 52, 2394 - 2416. doi:10.3758/s13428-020-01409-0

Examples

# common use-case: exclude movements that miss the target area and to go back
# movement 1:
x_vals1 <- c(0, 0.95, 1)
y_vals1 <- c(0, 1.3, 1)
# movement 2:
x_vals2 <- y_vals1
y_vals2 <- x_vals1
# movement 3:
x_vals3 <- c(0, -0.1, 0.5, 1)
y_vals3 <- c(0, 0.5, 0, 1)

# note that the first two movements are symmetric to the ideal line:
plot(x_vals1, y_vals1, type = "l", xlim = c(-0.1, 1.3), ylim = c(-0.1, 1.3))
lines(x_vals2, y_vals2, type = "l")
lines(x_vals3, y_vals3, type = "l")
lines(c(0, 1), c(0, 1), lty = "dashed", lwd = 2) # ideal

is_monotonic_along_ideal(x_vals1, y_vals1, warn = FALSE)
#> [1] FALSE
is_monotonic_along_ideal(x_vals2, y_vals2, warn = FALSE)
#> [1] FALSE
is_monotonic_along_ideal(x_vals3, y_vals3, warn = FALSE)
#> [1] TRUE
# Note that the third movement is regarded as monotonic although both
# x and y coordinates are not.
# In contrast, excluding movements based on monotony of the y-coordinate
# would exclude the first and third movement:
is_monotonic(y_vals1, warn = FALSE)
#> [1] FALSE
is_monotonic(y_vals2, warn = FALSE)
#> [1] TRUE
is_monotonic(y_vals3, warn = FALSE)
#> [1] FALSE

# Also works if movements go into negative direction:
# movement 1:
x_vals1 <- c(0, -0.95, -1)
y_vals1 <- c(0, 1.3, 1)
# movement 3:
x_vals3 <- c(0, 0.1, -0.5, -1)
y_vals3 <- c(0, 0.5, 0, 1)

plot(x_vals1, y_vals1, type = "l", xlim = c(-1.3, 0.1), ylim = c(-0.1, 1.3))
lines(x_vals3, y_vals3, type = "l")
lines(-c(0, 1), c(0, 1), lty = "dashed", lwd = 2) # ideal

is_monotonic_along_ideal(x_vals1, y_vals1, warn = FALSE)
#> [1] FALSE
is_monotonic_along_ideal(x_vals3, y_vals3, warn = FALSE)
#> [1] TRUE