-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.qmd
171 lines (144 loc) · 8.77 KB
/
index.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
---
title: |
Die durstige Kuh: Wie Produktionsschocks im Schweizer Milchmarkt gefunden werden
description: |
Entwicklung eines mathematischen Modells zur Erkennung von extremen Änderungen der Milchproduktion
abstract: |
In diesem hypothetischen Blogbeitrag untersuchen wir einen innovativen Algorithmus, der in der Lage ist, Schocks in der Schweizer Milchproduktion zu identifizieren. Angesichts der zentralen Rolle, die die Milchwirtschaft in der Schweiz spielt, bietet dieser Algorithmus landwirtschaftlichen Betrieben und politischen Entscheidungsträgern ein mächtiges Werkzeug, um auf unvorhergesehene Veränderungen im Milchmarkt reagieren zu können. Durch die Analyse historischer Daten und aktueller Trends kann der Algorithmus frühzeitig Warnsignale erkennen, die auf potenzielle Störungen hinweisen. Dieser Beitrag beleuchtet die Funktionsweise des Algorithmus, seine praktische Anwendung und die möglichen Auswirkungen auf die Schweizer Landwirtschaft. Begleitet wird der Beitrag von einer humorvollen Illustration, die eine Schweizer Milchkuh zeigt, die scheinbar keine Milch mehr produzieren kann – eine spielerische Anspielung auf die ernsten Herausforderungen, die Schocks in der Milchproduktion darstellen können.
image: image.webp
categories:
- Milch
- Hitze
date: 2024-03-15
author: [Corinne Straub, Damian Oswald]
code-fold: true
execute:
echo: false
---
![](image.webp){width=60% fig-align="center"}
# Schreiben einer SPARQL-Abfrage
Zuallererst werden die Daten direkt über [agrarmarktdaten.ch](https://www.agrarmarktdaten.ch/) eingezogen. Die Daten sind als *Linked Open Data* verfügbar und können dementsprechend über eine SPARQL-Abfrage gezielt verknüpft und heruntergeladen werden.
```{r}
#| message: false
library(XML) #<1>
library(lubridate)
library(tidyverse)
library(ggplot2)
library(readr)
library(httr) #<1>
sparql_string <- paste0(#<2>
"PREFIX cube: <https://cube.link/>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX schema: <http://schema.org/>
PREFIX time: <http://www.w3.org/2006/time#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT DISTINCT
?measure
?year ?month
WHERE {
GRAPH <https://lindas.admin.ch/foag/agricultural-market-data> {
VALUES(?product) {
(<https://agriculture.ld.admin.ch/foag/product/4>) }
<https://agriculture.ld.admin.ch/foag/cube/MilkDairyProducts/Production_Quantity_Month> cube:observationSet ?observationSet .
?observationSet cube:observation ?observation .
?observation <https://agriculture.ld.admin.ch/foag/dimension/date> ?date .
?observation <https://agriculture.ld.admin.ch/foag/dimension/product> ?product .
?observation <https://agriculture.ld.admin.ch/foag/measure/quantity> ?measure .
}
?date time:year ?year.
OPTIONAL { ?date time:month ?month. }
}
")#<2>
query <- POST("https://ld.admin.ch/query",
add_headers("Accept" = "text/csv"),
content_type("application/x-www-form-urlencoded; charset=UTF-8"),
body = paste("query=", sparql_string, sep = ""))
data <- content(query, encoding = "UTF-8")
```
1. Die nötigen R packages werden an den Suchpfad angeheftet.
2. Hier wird eine SPARQL Abfrage geschrieben.
## Umrechnen der Daten
In einem ersten Schritt müssen die Daten für die Analyse vorbereitet werden. Dazu sehen wir sie uns in ihrer Grundstruktur an.
...
### Verschiedene Monate haben verschiedene Anzahl Tage
```{r}
with(data, paste(year, month, "01", sep = "-")) |>
as.Date() |>
days_in_month() ->
days_in_month
```
```{r}
data[,"milkPerDay"] <- data[,"measure"]/days_in_month * 0.001
TS <- ts(data$milkPerDay, start = 2001, frequency = 12)
y <- TS - decompose(TS)$seasonal
```
```{r}
#| label: fig-time-series
#| fig-format: svg
#| fig-cap: Die täglich produzierte Milchmenge über die Jahre (schwarz) sowie die saisonal korrigierte Milchmenge.
#| fig-width: 8
#| fig-height: 6
#| out-width: 100%
#| echo: false
par(mar = c(4,4,0,0)+0.1)
plot(TS, ylab = "Täglich produzierte Milchmenge [t]", xlab = "Zeit")
grid()
lines(y, col = "red", lwd = 2)
```
## Erkennung von schockähnlichen Produktionsveränderungen
Schockähnlichen Produktionsveränderungen in der Milchproduktion werden anhand des $z$-Wertes der Veränderung der täglichen Milchproduktion im Vergleich zum Vormonat erkannt. Spezifisch werden die Ereignisse nach deren Wahrscheinlichkeit sortiert. Der $z$-Wert wird wie folgt gerechnet.
$$z = \frac{\Delta y - \mu}{\sigma}$${#eq-z}
Hierbei ist $y$ die tägliche Milchproduktion, $\Delta y$ ist die *Veränderung* der täglichen Milchproduktion im Vergleich zum Vormonat, $\mu$ ist das Arithmetische Mittel von $\Delta y$ und $\sigma$ die Standardabweichung von $\Delta y$.
:::{.column-page-right}
```{r}
#| out-width: 100%
#| fig-format: svg
#| fig-height: 4
#| fig-width: 8
#| echo: false
z <- scale(diff(y))
layout(mat = matrix(c(1,1,1,2), ncol = 4))
par(mar = c(4,4,0,0)+0.1)
plot((yp <- diff(y)/mean(y)*100),
ylab = "Veränderung der Milchproduktion im Vergleich zum Vormonat [%]",
xlab = "Zeit",
ylim = c(-4,5.5))
grid()
xx <- seq(-5,6,l=1000)
yy <- dnorm(xx, mean = mean(yp), sd = sd(yp))
crit01 <- qnorm(0.01)*sd(yp)+mean(yp)
crit05 <- qnorm(0.05)*sd(yp)+mean(yp)
polygon(x = c(2000,2050,2050,2000), y = c(crit01,crit01,-10,-10), col = adjustcolor("red", 0.5), border = FALSE)
polygon(x = c(2000,2050,2050,2000), y = c(crit05,crit05,-10,-10), col = adjustcolor("red", 0.3),
border = FALSE)
box()
lines(yp)
h <- hist(yp, plot = FALSE, breaks = 20)
par(mar = c(4,0,0,0)+0.1)
plot.new()
plot.window(xlim = range(h$density), ylim = c(-4,5.5))
for (i in 1:length(h$density)) {
w <- unique(diff(h$mids))/2
polygon(x = c(0,0,h$density[i],h$density[i]),
y = c(h$mids[i]-w,h$mids[i]+w,h$mids[i]+w,h$mids[i]-w))
}
polygon(y = c(xx[xx<crit01], rev(xx[xx<crit01])), x = c(rep(0,length(yy[xx<crit01])), rev(yy[xx<crit01])), col = adjustcolor("red", 0.5), border = FALSE)
polygon(y = c(xx[xx<crit05], rev(xx[xx<crit05])), x = c(rep(0,length(yy[xx<crit05])), rev(yy[xx<crit05])), col = adjustcolor("red", 0.3), border = FALSE)
lines(x = yy, y = xx)
```
:::
## Wann hatten wir schockähnliche Zustände?
Im Rahmen unserer umfassenden Analyse des Milchproduktion präsentieren wir eine detaillierte Tabelle, die die Ergebnisse der Evaluierung von Milchdaten sowie die Identifizierung von Schockzuständen über einen längeren Zeitraum hinweg darstellt. Diese Tabelle ermöglicht es uns, einen tieferen Einblick in die Schwankungen der Milchqualität zu gewinnen, indem sie die Verteilung und Häufigkeit von Schockzuständen in diversen Jahren aufzeigt. Diese Beobachtungen sind essenziell für das Verständnis der zeitlichen Muster und der potenziellen externen Faktoren, die diese Zustände beeinflussen können. Durch die sorgfältige Untersuchung dieser Daten können wir nicht nur die Stabilität und Sicherheit der Milchversorgung gewährleisten, sondern auch gezielte Massnahmen zur Verbesserung der Milchqualität in Zeiten identifizierter Schockzustände entwickeln.
```{r}
df <- data.frame(tail(data,-1), z, z< qnorm(0.05))[,-1]
months <- c("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember")
yes <- c("Ja", "Nein")
colnames(df) <- c("Jahr", "Monat", "Milchmenge [t/d]", "z", "Extremwert")
df[,2] <- months[df[,2]]
df[,3] <- round(df[,3], 1)
df[,4] <- round(df[,4], 3)
df[,5] <- yes[as.integer(df[,5])+1]
reactable::reactable(df)
```
Die detaillierte Analyse und Bewertung der Milchproduktionsdaten, einschliesslich der identifizierten Schockzustände über verschiedene Zeiträume hinweg, ist in der nachstehenden Tabelle dargestellt. Bei dieser umfassenden Untersuchung konnten Schockzustände in unterschiedlichen Jahren festgestellt werden, die signifikante Auswirkungen auf die Qualität und Quantität der Milchproduktion hatten. Ein besonders hervorzuhebender Zeitpunkt ist der Spätsommer des Jahres 2002. In diesem Zeitraum wurde die Schweiz von einer aussergewöhnlich intensiven Hitzewelle heimgesucht. Die ungewöhnlich hohen Temperaturen hatten einen direkten und erheblichen Einfluss auf die Milchwirtschaft des Landes. Die extremen Wetterbedingungen führten zu einer signifikanten Beeinträchtigung der physiologischen Zustände der Milchkühe, was wiederum eine merkliche Reduktion in der Milchproduktion zur Folge hatte. Dieser Zeitraum dient als exemplarisches Beispiel für die Vulnerabilität der Milchwirtschaft gegenüber klimatischen Extremereignissen und unterstreicht die Notwendigkeit adaptiver Strategien zur Sicherstellung der Stabilität und Nachhaltigkeit der Milchproduktion unter sich verändernden Umweltbedingungen.
![Badegäste hatten Freude am Hitzesommer 2002, Kühe allerdings weniger. Die optimale Temperatur für die Milchproduktion liegt bei 10 °C -- wenn es zu heiss wird, leidet die Leistung.](heat.webp)