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