I am trying to calculate the distance (df$X_Lambert_72_m; df$Y_Lambert_72_m) of a individual over the different dates. In other words, the difference of position for B150 between df$date "1" & "2", "2" & "3", "3" & "4",...
Here I have the code to calculate the euclidian distance (df$X_Lambert_72_m; df$Y_Lambert_72_m) and between two dates
euclid <- function(x1, y1, x2, y2) { #Lambert already in cartesian meters
sqrt( (x1-x2)^2 (y1-y2)^2 )
}
df1 <- df %>%
select(ID, contains("Lambert"), date) %>%
pivot_wider(
id_cols = ID,
names_from = date,
values_from = contains("Lambert")
) %>%
group_by(ID) %>%
mutate(Dist1 = euclid(X_Lambert_72_m_1, Y_Lambert_72_m_1,
X_Lambert_72_m_2, Y_Lambert_72_m_2)) %>%
select(ID, Dist1)
df <- df %>% left_join(df1, by = "ID")
And I would like to loop the euclidian function but from dates "1"-"2" to dates n - n 1
Here is the dataset:
df <- structure(list(ID = c("B150", "B145", "B140", "B136", "B150",
"B145", "B140", "B136", "B150", "B145", "B140", "B136", "B150",
"B145", "B140", "B136"), Ellipsoid_height_m = c(155.5, 155.5,
155.4, 155.3, 155.5, 155.5, 155.4, 155.3, 155.5, 155.5, 155.4,
155.3, 155.5, 155.5, 155.4, 155.3), X_Lambert_72_m = c(232764.455,
232765.271, 232766.444, 232767.093, 232766.955, 232767.771, 232768.944,
232769.593, 232767.455, 232768.271, 232769.444, 232770.093, 232768.455,
232769.271, 232770.444, 232771.093), Y_Lambert_72_m = c(125994.937,
125996.489, 125997.991, 125998.854, 125994.937, 125996.489, 125997.991,
125998.854, 125994.937, 125996.489, 125997.991, 125998.854, 125994.937,
125996.489, 125997.991, 125998.854), Type = c("Pittag", "Pittag",
"Pittag", "Pittag", "Pittag", "Pittag", "Pittag", "Pittag", "Pittag",
"Pittag", "Pittag", "Pittag", "Pittag", "Pittag", "Pittag", "Pittag"
), date = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L,
3L, 3L, 4L, 4L, 4L, 4L), .Label = c("1", "2", "3", "4"), class = "factor")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -16L))
CodePudding user response:
Maybe you want something like this. You are really just grouping by ID and then calculating the distance using lead. Based on your example, I assume you want to always compare the current date to the next date. If you want to compare the current date to the last date, switch lead to lag. Also you can set the default for when there is no lead or lag term. Right now, it is NA.
library(tidyverse)
euclid <- function(x, y) {
sqrt( (x-lead(x))^2 (y-lead(y))^2 )
}
df |>
arrange(ID,date) |>
group_by(ID) |>
mutate(Dist1 = euclid(X_Lambert_72_m,Y_Lambert_72_m ))
#> # A tibble: 16 x 7
#> # Groups: ID [4]
#> ID Ellipsoid_height_m X_Lambert_72_m Y_Lambert_72_m Type date Dist1
#> <chr> <dbl> <dbl> <dbl> <chr> <fct> <dbl>
#> 1 B136 155. 232767. 125999. Pittag 1 2.5
#> 2 B136 155. 232770. 125999. Pittag 2 0.5
#> 3 B136 155. 232770. 125999. Pittag 3 1
#> 4 B136 155. 232771. 125999. Pittag 4 NA
#> 5 B140 155. 232766. 125998. Pittag 1 2.5
#> 6 B140 155. 232769. 125998. Pittag 2 0.5
#> 7 B140 155. 232769. 125998. Pittag 3 1
#> 8 B140 155. 232770. 125998. Pittag 4 NA
#> 9 B145 156. 232765. 125996. Pittag 1 2.5
#> 10 B145 156. 232768. 125996. Pittag 2 0.5
#> 11 B145 156. 232768. 125996. Pittag 3 1
#> 12 B145 156. 232769. 125996. Pittag 4 NA
#> 13 B150 156. 232764. 125995. Pittag 1 2.5
#> 14 B150 156. 232767. 125995. Pittag 2 0.5
#> 15 B150 156. 232767. 125995. Pittag 3 1
#> 16 B150 156. 232768. 125995. Pittag 4 NA
