<- function(weight_kg, height_m){
BMI / ((height_m)^2)
weight_kg
}
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
<- function(weight_kg, height_m){
BMI / ((height_m)^2)
weight_kg
}
BMI(100, 1.80)
[1] 30.8642
A function which converts degrees Celcius to Farenheight
<- function(celsius){
Celsius_to_Farenheight * (9/5)) + 32
(celsius
}
Celsius_to_Farenheight(20)
[1] 68
A function which calculates the (Euclidean) distance between two sets of coordinates (x1, y1 and x2,y2)
<- \(x1,x2,y1,y2){
euclidean_distance 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
<- read.delim("wildschwein_BE_2056.csv", ",", header = T)
wildschwein_alle
<- wildschwein_alle |>
wildschwein_filter filter(TierName %in% c("Rosa", "Sabi") &
>= "2015-04-01" &
DatetimeUTC <= "2015-04-15") DatetimeUTC
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
$DatetimeUTC <- as.POSIXct(wildschwein_filter$DatetimeUTC, format = "%Y-%m-%dT%H:%M:%OSZ", tz="UTC")
wildschwein_filter
<- 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
<- wildschwein_filter |>
sabi filter(TierName %in% "Sabi")
<- wildschwein_filter |>
rosa filter(TierName %in% "Rosa")
# Join Sabi and Rosa via DateTimeRound
<- inner_join(rosa, sabi, by = "DateTimeRound", suffix = c("_Rosa", "_Sabi"))
wildschwein_joined
# Function for Euclidean Distance
<- function(wildschwein_joined){
euclidean_distance sqrt((wildschwein_joined$E_Rosa - wildschwein_joined$E_Sabi)^2 + (wildschwein_joined$N_Rosa - wildschwein_joined$N_Sabi)^2)
}
# apply for Rosa and Sabi
$Eu_distance <- euclidean_distance(wildschwein_joined)
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)
<- wildschwein_joined |> filter(is_meeting == TRUE)
meets_data
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 |>
sabi_14 filter(
>= "2015-04-01" &
DateTimeRound <= "2015-04-04"
DateTimeRound
)
<- rosa |>
rosa_14 filter(
>= "2015-04-01" &
DateTimeRound <= "2015-04-04"
DateTimeRound
)
# 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'
) )