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
## 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
## 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”
##
## 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
## $`16`
## [1] 20.09062
## 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