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 |