Zadanie 1

Zadanie: Vyberte aspoň 10 riadkov z ľubovoľného riešenia predošlých úloh a identifikujte miesta, kde váš kód nie je v súlade so zvoleným štandardom (všeobecne rozšíreným štýlom) a vysvetlite, prečo je kód ťažšie čitateľný. Podľa tohto štýlu kód preformátujte.

Riešenie:

Vybraný kód z predchádzajúcich príspevkov. Existuje niekoľko faktorov, prečo kód nespĺňa vybraný štandard:
- Put spaces around all infix operators. - Commas should always have a space after. - Opening braces should never go on their own line and should always be followed by a new line. - Lines should not be more than 80 characters. - komentáre v kóde by mali vysvetľovať „prečo”, a nie „čo” alebo „ako”. Mali by začínať veľkým písmenom, tak ako veta – v prípade viacerých viet končiť bodkou.

#data.frame(den = c("Po", "Ut", "St", "Št", "Pi"), 
#           meranie = c(23, 20, 18, 26, 20),
#           predpoveď = c(20, 18, 16, 23, 21)
#           ) %>%
#  mutate(
#    den = forcats::as_factor(den) #den = as_factor(den,level = c("Po", "Ut", "St", "Št", "Pi"))
#  ) %>%
#  pivot_longer(cols = c(`meranie`,`predpoveď`),names_to = "druh", values_to = "teploty") %>%
#  print() %>%
#  ggplot(mapping = aes(x = den,y = teploty,group = druh, color = druh)) + 
#  geom_line()

Ref.

# data.frame(
#   den = c("Po", "Ut", "St", "Št", "Pi"),
#   meranie = c(23, 20, 18, 26, 20),
#   predpoveď = c(20, 18, 16, 23, 21)
# ) %>%
#   mutate(
#          den = forcats::as_factor(den)) %>% # Alebo den = as_factor(den,level = c("Po", "Ut", "St", "Št", "Pi")).
#          pivot_longer(
#            cols = c(`meranie`, `predpoveď`),
#            names_to = "druh",
#            values_to = "teploty"
#          ) %>%
#            print() %>%
#            ggplot(mapping = aes(
#              x = den,
#              y = teploty,
#              group = druh,
#              color = druh
#            )) +
#            geom_line()

Zadanie 2

Zadanie: Zvoľte si jednoduchú úlohu, ktorú ste riešili na predmete Programovanie v jazyku C (alebo inom) a implementujte ju v prostredí R, jednak ako kompilovateľný kód jazyka C, jednak interpretovateľný kód jazyka R (a overte funkčnosť na konkrétnom výpočte). Ak sa dá, navrhnite príklad riešenia tak, aby bol vidieť rozdiel medzi nimi v rýchlosti vykonania.

Riešenie:

Kod 1.

Porovnáme implementáciu numerického integrovania metódou lichoběžníkov v C s použitím Rcpp a v R, s rozdielom v rýchlosti vykonávania.

library(Rcpp)
# implemintacia v R
trapezoidalRuleR <- function(a, b, n) {
  h <- (b - a) / n
  sum <- (sin(a) + sin(b)) / 2
  for (i in 1:(n-1)) {
    x <- a + i * h
    sum <- sum + sin(x)
  }
  h * sum
}
trapezoidalRuleR(0, pi, 100)
## [1] 1.999836
# implemintacia v C
cppFunction('
  double trapezoidalRuleC(double a, double b, int n) {
    double h = (b - a) / n;
    double sum = (sin(a) + sin(b)) / 2.0;
    for (int i = 1; i < n; i++) {
      double x = a + i * h;
      sum += sin(x);
    }
    return h * sum;
  }
')
trapezoidalRuleC(0, pi, 100)
## [1] 1.999836
# Vykon v R
time_r <- system.time({
  trapezoidalRuleR(0, pi, 1000000)
})

# Vykon v C
time_c <- system.time({
  trapezoidalRuleC(0, pi, 1000000)
})

time_r
##    user  system elapsed 
##    0.05    0.00    0.09
time_c
##    user  system elapsed 
##    0.02    0.00    0.03

Kod 2. Z Technickej školy

Našiel som kód, ktorý som napísal na Technickej škole. Tu môžete vidieť, aký veľký je rozdiel medzi C a R. V tomto príklade použil metódu Monte Carlo na odhad plochy kruhu a následne na výpočet π. Metóda spočíva v generovaní náhodných bodov v obdĺžniku a zisťovaní, koľko z nich padne do vnútra kruhu.

set.seed(123)  # Pre reprodukovatelnost v R

# implemintacia v R
monteCarloPiR <- function(n) {
  count <- 0
  for (i in 1:n) {
    x <- runif(1, 0, 1)
    y <- runif(1, 0, 1)
    if (x^2 + y^2 <= 1) count <- count + 1
  }
  return(4 * count / n)
}
monteCarloPiR(1000000)
## [1] 3.141864
# implemintacia v C (runif pre iste cisla)
cppFunction('
  double monteCarloPiC(int n) {
    int count = 0;
    double x, y;
    for (int i = 0; i < n; i++) {
      x = R::runif(0, 1);
      y = R::runif(0, 1);
      if (x * x + y * y <= 1) count++;
    }
    return 4.0 * count / n;
  }
')
monteCarloPiC(1000000)
## [1] 3.142948
# Vykon v R
time_r <- system.time({
  monteCarloPiR(1000000)
})

# Vykon v C
time_c <- system.time({
  monteCarloPiC(1000000)
})

time_r
##    user  system elapsed 
##    2.20    0.78    3.38
time_c
##    user  system elapsed 
##    0.01    0.00    0.01

Zadanie3

Zadanie: Priemernú hodnotu dojazdu automobilov z datasetu mtcars vypočítajte súbežne (paralelne) podľa počtu valcov.

Riešenie:

Neviem ci to spravne urobil. Pretoze pise: “Error in mclapply(): ! ‘mc.cores’ > 1 is not supported on Windows”

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
library(parallel)

avg_mpg_func <- function(data) {
  return(mean(data$mpg))
}

# Nastavenie poctu jadier pre paralelnc spracovanie
cores <- detectCores()

# Rozdelenie dat podla počtu valcov
data_by_cyl <- split(mtcars, cores)

# Paralelny vypocet priemernej hodnoty dojazdu pre kazdu skupinu
cas <- system.time({
  avg_mpg <- lapply(data_by_cyl, avg_mpg_func) # Tu bolo mclaplly
})
cas
##    user  system elapsed 
##       0       0       0
# Vypis vysledkov
avg_mpg
## $`16`
## [1] 20.09062
c(cas)
##  user.self   sys.self    elapsed user.child  sys.child 
##          0          0          0         NA         NA

Zadanie 4

Zadanie: Rozdeľte dataset mtcars na dve tabuľky (s rôznymi stĺpcami) a uložte ich do súboru relačnej databázy. Pripojte sa na databázový systém, spojte obe tabuľky do jednej (podľa modelu auta ako kľúčového poľa) a zobrazte údaje o všetkých autách so šiestimi, priamo uloženými valcami.

Riešenie:

library(dplyr)
library(DBI)
library(RSQLite)

# Prva tabulka: technicke specifikacie
table_1 <- mtcars %>% select(hp, cyl, disp) %>% tibble::rownames_to_column(., var = "car_model")

# Druha tabulka: ostatne udaje
table_2 <- mtcars %>% select(mpg, drat, wt)%>% tibble::rownames_to_column(., var = "car_model")

db <- dbConnect(RSQLite::SQLite(), dbname = "mtcars_database.db")

# Zapis tabul
dbWriteTable(db, "table_1", table_1, overwrite = TRUE)
dbWriteTable(db, "table_2", table_2, overwrite = TRUE)

# Join table_1 a table_2 podla "car_model"
query <- "
SELECT *
FROM table_1
INNER JOIN table_2 USING(car_model)
WHERE table_1.cyl = 6
"
table_result <- dbGetQuery(db, query)

table_result
##        car_model  hp cyl  disp  mpg drat    wt
## 1      Mazda RX4 110   6 160.0 21.0 3.90 2.620
## 2  Mazda RX4 Wag 110   6 160.0 21.0 3.90 2.875
## 3 Hornet 4 Drive 110   6 258.0 21.4 3.08 3.215
## 4        Valiant 105   6 225.0 18.1 2.76 3.460
## 5       Merc 280 123   6 167.6 19.2 3.92 3.440
## 6      Merc 280C 123   6 167.6 17.8 3.92 3.440
## 7   Ferrari Dino 175   6 145.0 19.7 3.62 2.770
dbDisconnect(db)