R-ohjelmointi.org

Tilastotieteellistä ohjelmointia R-kielellä

Suomalaisten juhlapyhien ja kalenteriviikkojen päättely

Juhlapyhät voidaan joidenkin maiden osalta päätellä R:ssä vaikkapa TimeWarp-pakettia käyttäen. Paketista ei kuitenkaan löydy suomalaisia juhlapyhiä. Olen pitkään vältellyt niiden päättelyyn soveltuvan funktion kirjoittamista, koska pääsiäisen ajankohdan selvittäminen on mukamas ollut niin tuskallista. Sen jälkeen kun luin Wikipediasta, että parikin kaveria ovat jo 1800-luvulla kehittäneet kaavat sen paikan määrittämiseksi, moinen kynnys alkoi tuntua tekosyyltä. Ja äkkiäkös tuollaisen funktion tosiaan rykäisi kokoon.

Funktion koodi on:

pyhäpäivät <- function(vuosi) {
 
  #vuosi <- 2017
 
  # Lakisääteiset pyhäpäivät
  # Pysyvät
  uusivuosi <- as.Date(paste0(vuosi, "-01-01"))
  loppiainen <- as.Date(paste0(vuosi, "-01-06"))
  vappu <- as.Date(paste0(vuosi, "-05-01"))
  itsenäisyyspäivä <- as.Date(paste0(vuosi, "-12-06"))
  joulupäivä <- as.Date(paste0(vuosi, "-12-25"))
  tapaninpäivä <- as.Date(paste0(vuosi, "-12-25"))
 
  # Liikkuvat
  # Juhannus
  tmp <- data.frame(date=seq.Date(as.Date(paste0(vuosi, "-06-20")), as.Date(paste0(vuosi, "-06-26")), by="day"), weekday=NA)
  tmp$weekday <- weekdays(tmp$date)
  juhannuspäivä <- tmp$date[tmp$weekday=="lauantai"]
 
  # Pyhäinpäivä
  tmp <- data.frame(date=seq.Date(as.Date(paste0(vuosi, "-10-31")), as.Date(paste0(vuosi, "-11-06")), by="day"), weekday=NA)
  tmp$weekday <- weekdays(tmp$date)
  pyhäinpäivä <- tmp$date[tmp$weekday=="lauantai"]
 
  # Pääsiäinen
  a <- vuosi %% 19
  b <- vuosi %% 4
  c <- vuosi %% 7
  tmp <- as.numeric(substr(vuosi, 1, 2))
  tmp_osamaara <- floor(tmp / 2)
  tmp_jakojäännös <- tmp %% 2
  f <- ((tmp_osamaara + tmp_jakojäännös) + 14) %% 30
  d <- (19*a + f) %% 30
  g <- (tmp - floor(tmp/4)) - 10
  e <- (2*b + 4*c + 6*d + g) %% 7
 
  easter_month <- ifelse(d+e <= 9, "-03", "-04")
  easter_day <- paste0("-", formatC(ifelse(d+e <= 9, 22+d+e, d+e-9), digits=1, flag=0, format="d"))
  pääsiäispäivä <- as.Date(paste0(vuosi, easter_month, easter_day))
  pitkäperjantai <- pääsiäispäivä-2
  toinen_pääsiäispäivä <- pääsiäispäivä+1
 
  # Helatorstai
  helatorstai <- pääsiäispäivä+40-1
 
  #Helluntai
  helluntai <- pääsiäispäivä+50-1
 
 
  # Ei-viralliset, mutta usein vapaat ("merkkipäivät")
  vappuaatto <- as.Date(paste0(vuosi, "-04-30"))
  jouluaatto <- as.Date(paste0(vuosi, "-12-24"))
  juhannusaatto <- juhannuspäivä-1
  uudenvuodenaatto <- as.Date(paste0(vuosi, "-12-31"))
 
  res<-
    data.frame(
      juhlapäivä=c("uusivuosi", "loppiainen", "vappu", "itsenäisyyspäivä", "joulupäivä", "tapaninpäivä", "juhannuspäivä", "pyhäinpäivä", "pääsiäispäivä", "2. pääsiäispäivä", "pitkäperjantai", "helatorstai", "helluntai", "vappuaatto", "jouluaatto", "juhannusaatto", "uudenvuodenaatto"),
      päiväys=c(uusivuosi, loppiainen, vappu, itsenäisyyspäivä, joulupäivä, tapaninpäivä, juhannuspäivä, pyhäinpäivä, pääsiäispäivä, toinen_pääsiäispäivä, pitkäperjantai, helatorstai, helluntai, vappuaatto, jouluaatto, juhannusaatto, uudenvuodenaatto),
      virallinen=c(rep("virallinen", 13), rep("epävirallinen", 4))
    )
 
  res<-res[order(res$päiväys),]
 
  return(res)
 
}

Funktio vaatii syötteenä vain vuosiluvun, mutta sillä voi kerralla laskea isommallekin määrälle vuosia pyhäpäivien sijainnit, vaikkapa näin:

do.call(rbind, lapply(2017:2044, function(x) pyhäpäivät(x)))

Toinen suomalaista kalenteria koskeva erityispiirre on viikkonumeroiden käyttö. Suomalaiset viikkonumerot noudattavat ISO 8601 -standardia. Miten päivämäärät sitten saadaan muutettua viikkonumeroiksi? Erään ratkaisun tarjoaa paketti ISOweek, mutta saman voi tehdä ihan perus-R:lläkin. Tallennetaanpa vaikkapa vuoden 2020 pyhäpäivät objektiin v20, ja määritetään kullekin viikko strftime()-funktiolla käyttäen formaattina viikkoa (%V):

v20<-pyhäpäivät(2020)
v20$viikko<-strftime(v20$päiväys, format="%V")
 
         juhlapäivä    päiväys    virallinen viikko
1         uusivuosi 2020-01-01    virallinen     01
2        loppiainen 2020-01-06    virallinen     02
11   pitkäperjantai 2020-04-10    virallinen     15
9     pääsiäispäivä 2020-04-12    virallinen     15
10 2. pääsiäispäivä 2020-04-13    virallinen     16
14       vappuaatto 2020-04-30 epävirallinen     18
3             vappu 2020-05-01    virallinen     18
12      helatorstai 2020-05-21    virallinen     21
13        helluntai 2020-05-31    virallinen     22
16    juhannusaatto 2020-06-19 epävirallinen     25
7     juhannuspäivä 2020-06-20    virallinen     25
8       pyhäinpäivä 2020-10-31    virallinen     44
4  itsenäisyyspäivä 2020-12-06    virallinen     49
15       jouluaatto 2020-12-24 epävirallinen     52
5        joulupäivä 2020-12-25    virallinen     52
6      tapaninpäivä 2020-12-25    virallinen     52
17 uudenvuodenaatto 2020-12-31 epävirallinen     53


Category