BMI <- function(weight_kg, height_m){
weight_kg / ((height_m)^2)
}
BMI(100, 1.80)[1] 30.8642
Input: is the same as the word function
Task: Create 2 functions:
A function which calculates a persons BMI based on their height and weight weight = kilogram height = m
BMI <- function(weight_kg, height_m){
weight_kg / ((height_m)^2)
}
BMI(100, 1.80)[1] 30.8642
A function which converts degrees Celcius to Farenheight
Celsius_to_Farenheight <- function(celsius){
(celsius * (9/5)) + 32
}
Celsius_to_Farenheight(20)[1] 68
A function which calculates the (Euclidean) distance between two sets of coordinates (x1, y1 and x2,y2)
euclidean_distance <- \(x1,x2,y1,y2){
sqrt((x2-x1)^2 + (y2-y1)^2)
}
euclidean_distance(1,4,2,5)[1] 4.242641
In the next tasks we will look for “meet” patterns in our wild boar data. To simplify this, we will only use a subset of our wild boar data: The individuals Rosa and Sabi for the timespan 01.04.2015 - 15.04.2015. Use the dataset wildschwein_BE_2056.csv (on moodle). Import the csv as a data.frame and filter it with the aforementioned criteria. You do not need to convert the data.frame to an sf object.
library(readr)
library(dplyr)
Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
wildschwein_alle <- read.delim("wildschwein_BE_2056.csv", ",", header = T)
wildschwein_filter <- wildschwein_alle |>
filter(TierName %in% c("Rosa", "Sabi") &
DatetimeUTC >= "2015-04-01" &
DatetimeUTC <= "2015-04-15")Have a look at your dataset. You will notice that samples are taken at every full hour, quarter past, half past and quarter to. The sampling time is usually off by a couple of seconds.
To compare Rosa and Sabi’s locations, we first need to match the two animals temporally. For that we can use a join, but need identical time stamps to serve as a join key. We therefore need to slightly adjust our time stamps to a common, concurrent interval.
The task is therefore to round the minutes of DatetimeUTC to a multiple of 15 (00, 15, 30,45) and store the values in a new column1. You can use the lubridate function round_date() for this. See the examples here to see how this goes.
library(lubridate)
Attaching package: 'lubridate'
The following objects are masked from 'package:base':
date, intersect, setdiff, union
wildschwein_filter$DatetimeUTC <- as.POSIXct(wildschwein_filter$DatetimeUTC, format = "%Y-%m-%dT%H:%M:%OSZ", tz="UTC")
wildschwein_filter <- wildschwein_filter |>
mutate(DateTimeRound = round_date(DatetimeUTC, unit = "minutes")
)To measure the distance between concurrent locations, we need to follow the following steps.
# Split Rosa and Sabi in two data frames
sabi <- wildschwein_filter |>
filter(TierName %in% "Sabi")
rosa <- wildschwein_filter |>
filter(TierName %in% "Rosa")
# Join Sabi and Rosa via DateTimeRound
wildschwein_joined <- inner_join(rosa, sabi, by = "DateTimeRound", suffix = c("_Rosa", "_Sabi"))
# Function for Euclidean Distance
euclidean_distance <- function(wildschwein_joined){
sqrt((wildschwein_joined$E_Rosa - wildschwein_joined$E_Sabi)^2 + (wildschwein_joined$N_Rosa - wildschwein_joined$N_Sabi)^2)
}
# apply for Rosa and Sabi
wildschwein_joined$Eu_distance <- euclidean_distance(wildschwein_joined)
# Meeting yes or no
wildschwein_joined <- wildschwein_joined |>
mutate(
is_meeting = Eu_distance <= 100 # True if distance is 100m or less
)Now, visualize the meets spatially in a way that you think reasonable. For example in the plot as shows below. To produce this plot we:
library(ggplot2)
meets_data <- wildschwein_joined |> filter(is_meeting == TRUE)
ggplot() +
geom_point(data = rosa, aes(E,N, colour = "Rosa"), alpha = 0.2) +
geom_point(data = sabi, aes(E,N, colour = "Sabi"), alpha = 0.2) +
geom_point(data = meets_data, aes(x = E_Rosa, y = N_Rosa, colour = "Meets"), shape = 21, fill = "NA", size = 3, stroke = 1) +
scale_color_manual(values = c("Rosa" = "red", "Sabi" = "cyan", "Meets" = "black")) +
labs(colour = "Regular Locations") +
theme_minimal()Finally, you can nicely visualize the meeting patterns and trajectories in a Space-Time-Cube (Hägerstraand 1970) with the package plotly. There are some nice ressources available online.
library(plotly)
Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':
last_plot
The following object is masked from 'package:stats':
filter
The following object is masked from 'package:graphics':
layout
# Angenommen, "wildschwein_joined" enthält die Spalten für E (Easting), N (Northing), und Datetime
# Konvertiere den Datetime in eine numerische Form (Zeitstempel für die z-Achse)
wildschwein_joined <- wildschwein_joined |>
mutate(time_numeric = as.numeric(DatetimeUTC_Rosa))
# 3D Space-Time-Cube Plot erstellen
plot_ly() |>
# Rosa's Trajektorie (rote Linie)
add_trace(
data = rosa, type = 'scatter3d', x = ~E, y = ~N, z = ~(DateTimeRound), mode = "lines", name = "Rosa") |>
# Sabi's Trajektorie (blaue Linie)
add_trace(
data = sabi, type = 'scatter3d', x = ~E, y = ~N, z = ~(DateTimeRound), mode = "lines", name = "Sabi") |>
# Treffen (Meets) als schwarze Punkte
add_trace(
data = meets_data, type = 'scatter3d', x = ~E_Rosa, y = ~N_Rosa, z = ~(DateTimeRound), mode = "points", name = "Meets") |>
# Layout und Achsen benennen
layout(
title = 'Space-Time Cube: Rosa & Sabi Meets',
scene = list(
xaxis = list(title = 'Easting (E)'),
yaxis = list(title = 'Northing (N)'),
zaxis = list(title = 'Time (DateTime)'),
aspectmode = 'cube'
)
)# Filtering Date between 2015-04-01 and 2015-04-04
sabi_14 <- sabi |>
filter(
DateTimeRound >= "2015-04-01" &
DateTimeRound <= "2015-04-04"
)
rosa_14 <- rosa |>
filter(
DateTimeRound >= "2015-04-01" &
DateTimeRound <= "2015-04-04"
)
# new plotly
# 3D Space-Time-Cube Plot erstellen
plot_ly() |>
# Rosa's Trajektorie (rote Linie)
add_trace(
data = rosa_14, type = 'scatter3d', x = ~E, y = ~N, z = ~(DateTimeRound), mode = "lines", name = "Rosa") |>
# Sabi's Trajektorie (blaue Linie)
add_trace(
data = sabi_14, type = 'scatter3d', x = ~E, y = ~N, z = ~(DateTimeRound), mode = "lines", name = "Sabi") |>
# Treffen (Meets) als schwarze Punkte
add_trace(
data = meets_data, type = 'scatter3d', x = ~E_Rosa, y = ~N_Rosa, z = ~(DateTimeRound), mode = "points", name = "Meets") |>
# Layout und Achsen benennen
layout(
title = 'Space-Time Cube: Rosa & Sabi Meets',
scene = list(
xaxis = list(title = 'Easting (E)'),
yaxis = list(title = 'Northing (N)'),
zaxis = list(title = 'Time (DateTime)'),
aspectmode = 'cube'
)
)