knitr::opts_chunk$set(
    echo = TRUE,
    message = FALSE,
    warning = FALSE
)

Spracované a inšpirované Notebookom Jason Locklin: Introduction to R for Education Data Analysis and Visualization

Práca s údajmi

Tradičná práca s databázou

Pre prácu s údajmi (databázou) používame najčastejšie dátový typ .data.frame.. Je to tabuľka, ktorá pozostáva zo stĺpcov rozličných typov. Jeden riadok pritom predstavuje jeden záznam databázy.

Príklad

Údaje o športovcoch: meno, vek, počet odohraných zápasov a typ športu.

Meno <- c("Adam", "Ema", "Lukáš", "Natália")
Vek <- c(20, 19, 22, 21)
Zapasy <- c(15, 18, 12, 20)
Sport <- c("Futbal", "Tenis", "Hádzaná", "Basketbal")

Spojenie do tabuľky:

sportovci <- data.frame(Meno, Vek, Zapasy, Sport)
print(sportovci)

Takýmto spôsobom sa môžeme pozrieť na to, či hrá jednotlivec kolektívny šport alebo nie.

sportovci$Kolektivny <- sportovci$Sport %in% c("Futbal","Hádzaná","Basketbal")
print(sportovci)

Operácie s data.frame

print(sportovci$Vek)
[1] 20 19 22 21
print(mean(sportovci$Zapasy))
[1] 16.25
print(sportovci[Meno=="Ema",])
print(sportovci[4,])
print(sportovci[,2:4])      # druhý až štvrtý stĺpec
summary(sportovci)
     Meno                Vek            Zapasy     
 Length:4           Min.   :19.00   Min.   :12.00  
 Class :character   1st Qu.:19.75   1st Qu.:14.25  
 Mode  :character   Median :20.50   Median :16.50  
                    Mean   :20.50   Mean   :16.25  
                    3rd Qu.:21.25   3rd Qu.:18.50  
                    Max.   :22.00   Max.   :20.00  
    Sport           Kolektivny     
 Length:4           Mode :logical  
 Class :character   FALSE:1        
 Mode  :character   TRUE :3        
                                   
                                   
                                   

Zistenie najstaršieho športovca a maximum odohraných zápasov

max_vek <- max(sportovci$Vek)        
max_zapasy <- max(sportovci$Zapasy)  
max_vek; max_zapasy
[1] 22
[1] 20

Pridanie riadku

novy <- data.frame(Meno="Tomáš", Vek=23, Zapasy=16, Sport="Atletika")
novy$Kolektivny <- novy$Sport %in% c("Futbal","Hádzaná","Basketbal")
sportovci <- rbind(sportovci, novy)
print(sportovci)

Nový stĺpec „Priemer zápasov za rok“

sportovci$PriemerZaRok <- sportovci$Zapasy / 1
print(sportovci)

Tabuľky v prostredí kableextra

library(knitr)
library(kableExtra)

kable(
  sportovci,
  digits = 1,
  align = c("l","c","c","l","c","c"),
  caption = "Údaje o športovcoch"
) %>%
kable_styling(
    bootstrap_options = c("striped","hover","condensed","responsive"),
    full_width = FALSE,
    position = "center"
)
Údaje o športovcoch
Meno Vek Zapasy Sport Kolektivny PriemerZaRok
Adam 20 15 Futbal TRUE 15
Ema 19 18 Tenis FALSE 18
Lukáš 22 12 Hádzaná TRUE 12
Natália 21 20 Basketbal TRUE 20
Tomáš 23 16 Atletika FALSE 16

Tidyverse - moderná práca s údajmi

Tidyverse je súbor knižníc, ktoré majú zjednodušiť prácu s údajmi. Majú jednotný komunikačný štandard, vzájomne sa doplňujú.

# Load tidyverse
library(tidyverse)

dplyr - pre manipuláciu s údajmi

.dplyr. poskytuje základné možnosti manipulácie s údajmi, ako napr.:

  1. filter(): vyberá riadky

  2. select(): vyberá stĺpce

  3. mutate(): vytvára nové stĺpce tabuľky

  4. arrange(): triedi riadky

  5. summarise(): sumarizuje

V nasledovnej ukážke využijeme tzv. .pipes. %>% alebo %<% umožňuje posielať výsledky z jednej funkcie priamo do volanie nasledovnej funkcie. To umožňuje ľahšiu čitateľnosť kódov, konvencia sa ujala a má široké použitie.

Výber a triedenie

sportovci %>%
  filter(Zapasy > 15) %>%                  # Výber športovcov s viac ako 15 zápasmi
  arrange(desc(Zapasy)) %>%                # Zoradenie zostupne podľa zápasov
  kable() %>%
  kable_styling(
      bootstrap_options = c("striped","hover","condensed","responsive"),
      full_width = FALSE,
      position = "center"
  )
Meno Vek Zapasy Sport Kolektivny PriemerZaRok
Natália 21 20 Basketbal TRUE 20
Ema 19 18 Tenis FALSE 18
Tomáš 23 16 Atletika FALSE 16

Zoskupenie a sumarizácia

Zoskupenie podľa kolektívneho športu a priemerné zápasy + počet športovcov

sportovci %>%
  group_by(Kolektivny) %>%       # zoskupenie podľa kolektívneho športu a priemerné zápasy + počet športovcov
  summarise(
    PriemZapasov = mean(Zapasy),
    Pocet = n()
  ) %>%
  kable(caption="Priemerné zápasy podľa kolektívneho športu") %>%
  kable_styling(
      bootstrap_options = c("striped","hover","condensed","responsive"),
      full_width = FALSE,
      position = "center"
  )
Priemerné zápasy podľa kolektívneho športu
Kolektivny PriemZapasov Pocet
FALSE 17.00000 2
TRUE 15.66667 3

Vytváranie novej premennej

Tento kód pridá nový stĺpec „BonusZapasy“ a súčasne ku každému športovcovi hodnotenie „grade“ podľa počtu zápasov, pričom:

  • „A“ → športovec odohral 18 alebo viac zápasov,

  • „B“ → športovec odohral 15 až 17 zápasov,

  • „C“ → športovec odohral menej ako 15 zápasov.

sportovci %>%
  mutate(
    grade = case_when(
      Zapasy >= 18 ~ "A",
      Zapasy >= 15 ~ "B",
      TRUE ~ "C"
    ),
    BonusZapasy = Zapasy + 2      # Pridané bonusové zápasy
  ) %>%
  kable() %>%
  kable_styling(
      bootstrap_options = c("striped","hover","condensed","responsive"),
      full_width = FALSE,
      position = "center"
  )
Meno Vek Zapasy Sport Kolektivny PriemerZaRok grade BonusZapasy
Adam 20 15 Futbal TRUE 15 B 17
Ema 19 18 Tenis FALSE 18 A 20
Lukáš 22 12 Hádzaná TRUE 12 C 14
Natália 21 20 Basketbal TRUE 20 A 22
Tomáš 23 16 Atletika FALSE 16 B 18

Stĺpcový graf počtu zápasov podľa športovcov

library(ggplot2)

ggplot(sportovci, aes(x = Meno, y = Zapasy, fill = Sport)) +
  geom_col() +                              # stĺpcový graf
  labs(title = "Počet zápasov športovcov",
       x = "Meno",
       y = "Počet zápasov") +
  theme_minimal() +
  theme(panel.background = element_rect(fill = "lightyellow"),
        plot.background = element_rect(fill = "lightblue"))

Horizontálny stĺpcový graf

ggplot(sportovci, aes(x = reorder(Meno, Zapasy), y = Zapasy, fill = Sport)) +
  geom_col() +
  coord_flip() +                            # otočenie osí
  labs(title = "Počet zápasov podľa športovcov",
       x = "Meno",
       y = "Počet zápasov") +
  theme_minimal()

LS0tCnRpdGxlOiAiUHLDoWNhIHMgZGF0YWLDoXpvdSIKYXV0aG9yOiAiTGluZGEgS2FrYXNvdsOhICA8YnI+CihzIHZ5dcW+aXTDrW0gdmVyZWpuZSBkb3N0dXBuw71jaCBrw7Nkb3YpIgpkYXRlOiAiT2t0b2JlciAyMDI1IgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdGhlbWU6IGNlcnVsZWFuCiAgICBoaWdobGlnaHQ6IHRhbmdvCmVkaXRvcl9vcHRpb25zOiAKICBtYXJrZG93bjogCiAgICB3cmFwOiA3MgotLS0KCmBgYHtyfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgICBlY2hvID0gVFJVRSwKICAgIG1lc3NhZ2UgPSBGQUxTRSwKICAgIHdhcm5pbmcgPSBGQUxTRQopCmBgYAoKU3ByYWNvdmFuw6kgYSBpbsWhcGlyb3ZhbsOpIE5vdGVib29rb20KW0phc29uIExvY2tsaW46IEludHJvZHVjdGlvbiB0byBSIGZvciBFZHVjYXRpb24gRGF0YSBBbmFseXNpcyBhbmQgVmlzdWFsaXphdGlvbl0oaHR0cDovL3JwdWJzLmNvbS9qYXNvbkwvTGFuZEwpe3RhcmdldD0iX2JsYW5rIiByZWw9Im5vb3BlbmVyIn0KCgojIFByw6FjYSBzIMO6ZGFqbWkKCiMjIFRyYWRpxI1uw6EgcHLDoWNhIHMgZGF0YWLDoXpvdQoKUHJlIHByw6FjdSBzIMO6ZGFqbWkgKGRhdGFiw6F6b3UpIHBvdcW+w612YW1lIG5hasSNYXN0ZWrFoWllIGTDoXRvdsO9IHR5cCAuZGF0YS5mcmFtZS4uIEplIHRvIHRhYnXEvmthLCBrdG9yw6EgcG96b3N0w6F2YSB6byBzdMS6cGNvdiByb3psacSNbsO9Y2ggdHlwb3YuIEplZGVuIHJpYWRvayBwcml0b20gcHJlZHN0YXZ1amUgamVkZW4gesOhem5hbSBkYXRhYsOhenkuCgojIyMgUHLDrWtsYWQKCsOaZGFqZSBvIMWhcG9ydG92Y29jaDogbWVubywgdmVrLCBwb8SNZXQgb2RvaHJhbsO9Y2ggesOhcGFzb3YgYSB0eXAgxaFwb3J0dS4KCmBgYHtyfQpNZW5vIDwtIGMoIkFkYW0iLCAiRW1hIiwgIkx1a8OhxaEiLCAiTmF0w6FsaWEiKQpWZWsgPC0gYygyMCwgMTksIDIyLCAyMSkKWmFwYXN5IDwtIGMoMTUsIDE4LCAxMiwgMjApClNwb3J0IDwtIGMoIkZ1dGJhbCIsICJUZW5pcyIsICJIw6FkemFuw6EiLCAiQmFza2V0YmFsIikKYGBgCgojIyBTcG9qZW5pZSBkbyB0YWJ1xL5reToKCmBgYHtyfQpzcG9ydG92Y2kgPC0gZGF0YS5mcmFtZShNZW5vLCBWZWssIFphcGFzeSwgU3BvcnQpCnByaW50KHNwb3J0b3ZjaSkKYGBgCgojIyMjIFRha8O9bXRvIHNww7Rzb2JvbSBzYSBtw7TFvmVtZSBwb3pyaWXFpSBuYSB0bywgxI1pIGhyw6EgamVkbm90bGl2ZWMga29sZWt0w612bnkgxaFwb3J0IGFsZWJvIG5pZS4KCmBgYHtyfQpzcG9ydG92Y2kkS29sZWt0aXZueSA8LSBzcG9ydG92Y2kkU3BvcnQgJWluJSBjKCJGdXRiYWwiLCJIw6FkemFuw6EiLCJCYXNrZXRiYWwiKQpwcmludChzcG9ydG92Y2kpCmBgYAoKIyMgT3BlcsOhY2llIHMgZGF0YS5mcmFtZQoKYGBge3J9CnByaW50KHNwb3J0b3ZjaSRWZWspCnByaW50KG1lYW4oc3BvcnRvdmNpJFphcGFzeSkpCnByaW50KHNwb3J0b3ZjaVtNZW5vPT0iRW1hIixdKQpwcmludChzcG9ydG92Y2lbNCxdKQpwcmludChzcG9ydG92Y2lbLDI6NF0pICAgICAgIyBkcnVow70gYcW+IMWhdHZydMO9IHN0xLpwZWMKc3VtbWFyeShzcG9ydG92Y2kpCmBgYAoKIyMjIFppc3RlbmllIG5hanN0YXLFoWllaG8gxaFwb3J0b3ZjYSBhIG1heGltdW0gb2RvaHJhbsO9Y2ggesOhcGFzb3YKCmBgYHtyfQptYXhfdmVrIDwtIG1heChzcG9ydG92Y2kkVmVrKSAgICAgICAgCm1heF96YXBhc3kgPC0gbWF4KHNwb3J0b3ZjaSRaYXBhc3kpICAKbWF4X3ZlazsgbWF4X3phcGFzeQpgYGAKCgojIyMgUHJpZGFuaWUgcmlhZGt1CgpgYGB7cn0Kbm92eSA8LSBkYXRhLmZyYW1lKE1lbm89IlRvbcOhxaEiLCBWZWs9MjMsIFphcGFzeT0xNiwgU3BvcnQ9IkF0bGV0aWthIikKbm92eSRLb2xla3Rpdm55IDwtIG5vdnkkU3BvcnQgJWluJSBjKCJGdXRiYWwiLCJIw6FkemFuw6EiLCJCYXNrZXRiYWwiKQpzcG9ydG92Y2kgPC0gcmJpbmQoc3BvcnRvdmNpLCBub3Z5KQpwcmludChzcG9ydG92Y2kpCmBgYAoKIyMjIE5vdsO9IHN0xLpwZWMg4oCeUHJpZW1lciB6w6FwYXNvdiB6YSByb2vigJwKCmBgYHtyfQpzcG9ydG92Y2kkUHJpZW1lclphUm9rIDwtIHNwb3J0b3ZjaSRaYXBhc3kgLyAxCnByaW50KHNwb3J0b3ZjaSkKYGBgCgojIyMgVGFidcS+a3kgdiBwcm9zdHJlZMOtIGthYmxlZXh0cmEKCmBgYHtyfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgprYWJsZSgKICBzcG9ydG92Y2ksCiAgZGlnaXRzID0gMSwKICBhbGlnbiA9IGMoImwiLCJjIiwiYyIsImwiLCJjIiwiYyIpLAogIGNhcHRpb24gPSAiw5pkYWplIG8gxaFwb3J0b3Zjb2NoIgopICU+JQprYWJsZV9zdHlsaW5nKAogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiLCJyZXNwb25zaXZlIiksCiAgICBmdWxsX3dpZHRoID0gRkFMU0UsCiAgICBwb3NpdGlvbiA9ICJjZW50ZXIiCikKYGBgCgojIyBUaWR5dmVyc2UgLSBtb2Rlcm7DoSBwcsOhY2EgcyDDumRham1pCgpUaWR5dmVyc2UgamUgc8O6Ym9yIGtuacW+bsOtYywga3RvcsOpIG1hasO6IHpqZWRub2R1xaFpxaUgcHLDoWN1IHMgw7pkYWptaS4gTWFqw7ogamVkbm90bsO9IGtvbXVuaWthxI1uw70gxaF0YW5kYXJkLCB2esOham9tbmUgc2EgZG9wbMWIdWrDui4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgTG9hZCB0aWR5dmVyc2UKbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKIyMjICBkcGx5ciAtIHByZSBtYW5pcHVsw6FjaXUgcyDDumRham1pCgouZHBseXIuIHBvc2t5dHVqZSB6w6FrbGFkbsOpIG1vxb5ub3N0aSBtYW5pcHVsw6FjaWUgcyDDumRham1pLCBha28gbmFwci46IAoKMS4gZmlsdGVyKCk6IHZ5YmVyw6EgcmlhZGt5IAoKMS4gc2VsZWN0KCk6IHZ5YmVyw6Egc3TEunBjZSAKCjEuIG11dGF0ZSgpOiB2eXR2w6FyYSBub3bDqSBzdMS6cGNlIHRhYnXEvmt5IAoKMS4gYXJyYW5nZSgpOiB0cmllZGkgcmlhZGt5IAoKMS4gc3VtbWFyaXNlKCk6IHN1bWFyaXp1amUKClYgbmFzbGVkb3ZuZWogdWvDocW+a2Ugdnl1xb5pamVtZSB0enYuIC5waXBlcy4gJT4lIGFsZWJvICU8JSB1bW/FvsWIdWplIHBvc2llbGHFpSB2w71zbGVka3kgeiBqZWRuZWogZnVua2NpZSBwcmlhbW8gZG8gdm9sYW5pZSBuYXNsZWRvdm5laiBmdW5rY2llLiBUbyB1bW/FvsWIdWplIMS+YWjFoWl1IMSNaXRhdGXEvm5vc8WlIGvDs2Rvdiwga29udmVuY2lhIHNhIHVqYWxhIGEgbcOhIMWhaXJva8OpIHBvdcW+aXRpZS4KCiMjIyMgVsO9YmVyIGEgdHJpZWRlbmllCgpgYGB7cn0Kc3BvcnRvdmNpICU+JQogIGZpbHRlcihaYXBhc3kgPiAxNSkgJT4lICAgICAgICAgICAgICAgICAgIyBWw71iZXIgxaFwb3J0b3Zjb3YgcyB2aWFjIGFrbyAxNSB6w6FwYXNtaQogIGFycmFuZ2UoZGVzYyhaYXBhc3kpKSAlPiUgICAgICAgICAgICAgICAgIyBab3JhZGVuaWUgem9zdHVwbmUgcG9kxL5hIHrDoXBhc292CiAga2FibGUoKSAlPiUKICBrYWJsZV9zdHlsaW5nKAogICAgICBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIsInJlc3BvbnNpdmUiKSwKICAgICAgZnVsbF93aWR0aCA9IEZBTFNFLAogICAgICBwb3NpdGlvbiA9ICJjZW50ZXIiCiAgKQpgYGAKCiMjIyMgWm9za3VwZW5pZSBhIHN1bWFyaXrDoWNpYQoKWm9za3VwZW5pZSBwb2TEvmEga29sZWt0w612bmVobyDFoXBvcnR1IGEgcHJpZW1lcm7DqSB6w6FwYXN5ICsgcG/EjWV0IMWhcG9ydG92Y292CgpgYGB7cn0Kc3BvcnRvdmNpICU+JQogIGdyb3VwX2J5KEtvbGVrdGl2bnkpICU+JSAgICAgICAjIHpvc2t1cGVuaWUgcG9kxL5hIGtvbGVrdMOtdm5laG8gxaFwb3J0dSBhIHByaWVtZXJuw6kgesOhcGFzeSArIHBvxI1ldCDFoXBvcnRvdmNvdgogIHN1bW1hcmlzZSgKICAgIFByaWVtWmFwYXNvdiA9IG1lYW4oWmFwYXN5KSwKICAgIFBvY2V0ID0gbigpCiAgKSAlPiUKICBrYWJsZShjYXB0aW9uPSJQcmllbWVybsOpIHrDoXBhc3kgcG9kxL5hIGtvbGVrdMOtdm5laG8gxaFwb3J0dSIpICU+JQogIGthYmxlX3N0eWxpbmcoCiAgICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsImhvdmVyIiwiY29uZGVuc2VkIiwicmVzcG9uc2l2ZSIpLAogICAgICBmdWxsX3dpZHRoID0gRkFMU0UsCiAgICAgIHBvc2l0aW9uID0gImNlbnRlciIKICApCmBgYAoKIyMjIyBWeXR2w6FyYW5pZSBub3ZlaiBwcmVtZW5uZWoKClRlbnRvIGvDs2QgcHJpZMOhIG5vdsO9IHN0xLpwZWMg4oCeQm9udXNaYXBhc3nigJwgYSBzw7rEjWFzbmUga3Uga2HFvmTDqW11IMWhcG9ydG92Y292aSBob2Rub3RlbmllIOKAnmdyYWRl4oCcIHBvZMS+YSBwb8SNdHUgesOhcGFzb3YsIHByacSNb206CgoqIOKAnkHigJwg4oaSIMWhcG9ydG92ZWMgb2RvaHJhbCAxOCBhbGVibyB2aWFjIHrDoXBhc292LAoKKiDigJ5C4oCcIOKGkiDFoXBvcnRvdmVjIG9kb2hyYWwgMTUgYcW+IDE3IHrDoXBhc292LAoKKiDigJ5D4oCcIOKGkiDFoXBvcnRvdmVjIG9kb2hyYWwgbWVuZWogYWtvIDE1IHrDoXBhc292LgoKYGBge3J9CnNwb3J0b3ZjaSAlPiUKICBtdXRhdGUoCiAgICBncmFkZSA9IGNhc2Vfd2hlbigKICAgICAgWmFwYXN5ID49IDE4IH4gIkEiLAogICAgICBaYXBhc3kgPj0gMTUgfiAiQiIsCiAgICAgIFRSVUUgfiAiQyIKICAgICksCiAgICBCb251c1phcGFzeSA9IFphcGFzeSArIDIgICAgICAjIFByaWRhbsOpIGJvbnVzb3bDqSB6w6FwYXN5CiAgKSAlPiUKICBrYWJsZSgpICU+JQogIGthYmxlX3N0eWxpbmcoCiAgICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsImhvdmVyIiwiY29uZGVuc2VkIiwicmVzcG9uc2l2ZSIpLAogICAgICBmdWxsX3dpZHRoID0gRkFMU0UsCiAgICAgIHBvc2l0aW9uID0gImNlbnRlciIKICApCmBgYAojIFN0xLpwY292w70gZ3JhZiBwb8SNdHUgesOhcGFzb3YgcG9kxL5hIMWhcG9ydG92Y292CgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQoKZ2dwbG90KHNwb3J0b3ZjaSwgYWVzKHggPSBNZW5vLCB5ID0gWmFwYXN5LCBmaWxsID0gU3BvcnQpKSArCiAgZ2VvbV9jb2woKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzdMS6cGNvdsO9IGdyYWYKICBsYWJzKHRpdGxlID0gIlBvxI1ldCB6w6FwYXNvdiDFoXBvcnRvdmNvdiIsCiAgICAgICB4ID0gIk1lbm8iLAogICAgICAgeSA9ICJQb8SNZXQgesOhcGFzb3YiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAibGlnaHR5ZWxsb3ciKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJsaWdodGJsdWUiKSkKYGBgCgojIEhvcml6b250w6Fsbnkgc3TEunBjb3bDvSBncmFmIAoKYGBge3J9CmdncGxvdChzcG9ydG92Y2ksIGFlcyh4ID0gcmVvcmRlcihNZW5vLCBaYXBhc3kpLCB5ID0gWmFwYXN5LCBmaWxsID0gU3BvcnQpKSArCiAgZ2VvbV9jb2woKSArCiAgY29vcmRfZmxpcCgpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBvdG/EjWVuaWUgb3PDrQogIGxhYnModGl0bGUgPSAiUG/EjWV0IHrDoXBhc292IHBvZMS+YSDFoXBvcnRvdmNvdiIsCiAgICAgICB4ID0gIk1lbm8iLAogICAgICAgeSA9ICJQb8SNZXQgesOhcGFzb3YiKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKCg==