HovnikK15 / APPR-2017-18

Repozitorij z gradivi za predmet Analiza podatkov s programom R v študijskem letu 2017/18
MIT License
0 stars 0 forks source link

Težave pri tabeli #1

Open HovnikK15 opened 6 years ago

HovnikK15 commented 6 years ago

Pozdravljeni, kljub namigu, mi še vedno ni jasno kako naj spremenim kodo, da mi bo tablela Html1 ter tabela 9 prikazovala Spol in leto v enem stolpcu, namesto v dveh stolpcih Moški in Ženske

Prav tako me še zanima, če je možno pri grafu, da mi za vsako leto kaže 4 stolpce in sicer (priseljeni moški, priseljene ženske ter enako za odseljene) ker do zdaj mi kaže le dva stolpca za moške in ženske ter vsota vseh migrantov, torej št. priseljenih in odseljenih žensk..

jaanos commented 6 years ago

V uvozihtml2 si pomagaj s funkcijo melt iz knjižnice reshape2. Leta in števila bo potem še treba pretvoriti v števila:

  colnames(tabela) <- c("Dejavnost", "Leto", "Drzavljanstvo", "Moški", "Ženske")
  tabela <- melt(tabela, measure.vars = c("Moški", "Ženske"),
                 variable.name = "Spol", value.name = "Stevilo") %>%
    mutate(Leto = parse_number(Leto), Stevilo = parse_number(Stevilo))

Za razpredelnico tabela9 lahko uvoz narediš tako (po zgledu anamkravanja#1):

uvozi9 <- function() {
  tab9 <- read_csv2(file="podatki/05N1004Ss.csv",
                   locale = locale(encoding = "Windows-1250"), skip = 2,  n_max = 43)
  stolpci <- data.frame(leto = colnames(tab9) %>% { gsub("X.*", NA, .) } %>% parse_number(),
                        spol = tab9[1, ] %>% unlist()) %>% fill(leto) %>%
    apply(1, paste, collapse = "")
  stolpci[1:2] <- c("Vrsta_migrantov", "Starostna_skupina")
  colnames(tab9) <- stolpci
  tab9 <- tab9[-1, ] %>% fill(Vrsta_migrantov) %>% drop_na(Starostna_skupina) %>%
    filter(!grepl("SKUPAJ", Starostna_skupina)) %>%
    melt(id.vars = 1:2, variable.name = "stolpec", value.name = "Stevilo") %>%
    mutate(stolpec = parse_character(stolpec)) %>%
    transmute(Vrsta_migrantov, Starostna_skupina,
              Leto = stolpec %>% strapplyc("^([0-9]+)") %>% unlist() %>% parse_number(),
              Spol = stolpec %>% strapplyc("([^0-9]+)$") %>% unlist() %>% factor(),
              Stevilo)
  return(tab9)
}

Če hočeš podatke v grafu ločiti glede na dva stolpca, ju lahko nekako skombiniraš - najlažje kar s paste, npr.

graf2 <- ggplot(tabela1, aes(x = factor(Leto), y = Stevilo, fill = paste(Spol, Vrsta_migrantov))) +
  geom_bar(stat = "identity", position = "dodge") +
  xlab("Leto") + ylab("Število") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +
  ggtitle("Število migracij po letih") +
  guides(fill = guide_legend("Spol in vrsta"))

Še to: opažam, da v libraries.r uvažaš knjižnico ggplot, ki pa ne obstaja. Uvoz knjižnice ggplot2 je že narejen v istem programu. V vizualizacija.r grafov ne izpisuj - lahko jih pripraviš, izpisal pa jih boš na želenem mestu v poročilu.

HovnikK15 commented 6 years ago

Najlepša hvala za odgovor. Obe tabeli mi zdaj delujeta. Imam pa nov problem s tabelo 23. pri UVOZI3, saj je potrebno dvakratno dopolnjevanje tako let kot tudi državljanstva (Tuji ter državljani RS). Poskusil sem po zgledu vendar neuspešno. Prav tako se je pojavila nova težava pri grafih. Koda deluje, le da zdaj ne sešteje več skupaj vseh starostnih skupin oz. ne vem kaj stori. Graf je izredno ne pregleden. Dodal sem nove tabele vendar z istimi podatki in mi zaradi tega ne naredi več le dva oz. 4 stolpce temveč ogromno črtic.

Pa še vprašanje od zemljevidov: vse imena držav bom zapisal v angleškem jeziku. Me pa zanima, kako naj napišem prevod za Severno in Srednjo Ameriko, saj zemljevid uporablja imena za oba dela, v moji razpredelnici pa se podatki navezujejo na obe skupaj. Kako naj naredim, da bo na koncu za Severno in Sredno Ameriko pobarvana oba dela z enako barvo?

jaanos commented 6 years ago

Takole bi šel uvoz:

uvozi23 <- function() {
  tab3 <- read_csv2(file="podatki/tabela23.csv",
                    locale = locale(encoding = "Windows-1250"), skip = 3,  n_max = 45)
  stolpci <- data.frame(drzavljanstvo = tab3[1, ] %>% unlist(),
                        leto = colnames(tab3) %>% { gsub("X.*", NA, .) } %>% parse_number(),
                        spol = tab3[2, ] %>% unlist()) %>%
    fill(leto, drzavljanstvo) %>% apply(1, paste, collapse = "")
  stolpci[1:2] <- c("Vrsta_migrantov", "Starostna_skupina")
  colnames(tab3) <- stolpci
  tab3 <- tab3[-c(1:2), ] %>% fill(Vrsta_migrantov) %>% drop_na(Starostna_skupina) %>%
    melt(id.vars = 1:2, variable.name = "stolpec", value.name = "Stevilo") %>%
    mutate(stolpec = parse_character(stolpec)) %>%
    transmute(Vrsta_migrantov, Starostna_skupina,
              Leto = stolpec %>% strapplyc("([0-9]+)") %>% unlist() %>% parse_number(),
              Spol = stolpec %>% strapplyc("([^0-9]+)$") %>% unlist() %>% factor(),
              Drzavljanstvo = stolpec %>% strapplyc("^([^0-9]+)") %>% unlist() %>% factor(),
              Stevilo = parse_number(Stevilo))
  return(tab3)
}

Državljanstvo je torej v prvi, spol pa v drugi vrstici. Leto je postavljeno vmes, tako da je mogoče iz sestavljenega niza potem pobrati del pred številkami in po njih. Funkcijo sem tudi preimenoval, saj imaš kasneje še eno funkcijo uvozi3.

V zgornjem uvozu je potrebno stolpec Stevilo pretvoriti iz faktorja v števila - enako bo treba narediti še pri razpredelnicah html1, tabela1, tabela2 in tabela4. To je tudi razlog, zakaj se na grafih pojavi toliko oznak na osi y. Ker imaš npr. v tabela1 za vsako leto in vrsto migrantov podatke za vsak spol in starostno skupino, ti na grafu prikaže točko za vsak podatek. Če želiš vrednosti sešteti, uporabi group_by in summarise, npr.

graf1 <- ggplot(tabela1 %>% group_by(Leto, Vrsta_migrantov) %>% summarise(Stevilo = sum(Stevilo)),
                aes(x = Leto, y = Stevilo, color = Vrsta_migrantov)) +
   geom_line(size = 1) +
  geom_point(size = 1.5) +
  xlab("Leto") + ylab("Število") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) + 
  ggtitle("Število dijakov glede na vrsto štipendije po letih") +
  scale_color_discrete("Vrsta migrantov")

Podobno bo treba narediti pri preostalih dveh grafih - spremeniti bo treba le, po katerih stolpcih združuješ (group_by).

Na zemljevidu je smiselno prikazati podatke za posamezne države in ne celotne celine - pravzaprav bi bilo treba te podatke odstraniti, saj jih lahko izpelješ iz preostalih. Sicer pa, če bi se odločil prikazati podatke za celotne celine, je v stolpcu CONTINENT v zemljevidu vrednost "North America" uporabljena tako za Severno kot za Srednjo Ameriko.

HovnikK15 commented 6 years ago

Pozdravljeni, zopet potrebujem pomoč. Uspelo mi je narisati zemljevid, opazil sem pa le, da mi ne bere vseh podatkov. Ustvaril sem novo tabelo stevilo.selitev, v kateri si vsi podatki, ki jih zelim predstaviti na zemljevidu. A po nekaksnem nakljucju se na zemljevidu prikaze le nekaj od teh podatkov (recimo, ce posebej filtriram rezultat na zemljevidu za "Francijo" koda deluje, če pa isto želim narediti za "AFRIKO" pa koda ne deluje) Podobno mi je na začetku v tej tabeli stevilo.selitev za odseljene prebivalce vrnilo vsoto za le tri države (Albanija, Bosna in še ena) in ne vem zakaj mi ne naredi lepo vsega, če koda za priseljene normalno deluje. (jaz sem zato ustvaril tabelo za samo priseljene prebivalce)

potem pa še še zanima, kaj bi lahko spremenil pri tabeli html2, kjer imam link iz SURS-a, ta stran pa deluje nekako tako, da se vsak dan linki spreminjajo in mi trenutni link deluje le en dan..in potem moram vedno znova kopirati nov link tabele, če želim, da se ukaz te kode zaključi in prikaže tabelo.

Najlepša hvala za pomoč!

jaanos commented 6 years ago

Problem je v tem, da imaš nekatere podatke za države, druge pa za celine. Tako bi bilo treba posebej pobarvati celotne celine, potem pa dodati podatke za posamezne države. Nekaj takšnega bi šlo:

stevilo.selitev.eng <- stevilo.selitev %>%
  mutate(Drzava_drzavljanstva = drzave.eng[Drzava_drzavljanstva])

zemljevid.selitve <- ggplot() + aes(x = long, y = lat, group = group, fill = Stevilo) +
  geom_polygon(data = right_join(stevilo.selitev.eng, evropa,
                                 by = c("Drzava_drzavljanstva" = "CONTINENT"))) +
  geom_polygon(data = inner_join(stevilo.selitev.eng, evropa,
                                 by = c("Drzava_drzavljanstva" = "SOVEREIGNT")),
               color = "black")

Problem takega pristopa je ta, da je večina tvojih podatkov za Evropo, kjer so številke največje - tako bo večina zemljevida iste barve. Bolje bo, če narišeš dva zemljevida - enega, ki prikazuje podatke samo po celinah (pri čemer Evropo obravnavaš posebej, saj bi sicer vse ostale celine bile enake barve), in enega, ki prikazuje podatke samo za Evropo (ter morda še za ZDA in Kanado). Nekako tako bi šlo:

selitve.eng <- tabela2 %>% filter(Vrsta_migrantov == "Priseljeni iz tujine") %>% 
  group_by(Drzava_drzavljanstva) %>% summarise(Stevilo = sum(Stevilo)) %>%
  mutate(Drzava_drzavljanstva = drzave.eng[Drzava_drzavljanstva])

zemljevid.selitve.celine <- ggplot() + aes(x = long, y = lat, group = group, fill = Stevilo) +
  geom_polygon(data = evropa %>% filter(CONTINENT != "Europe") %>%
                 left_join(selitve.eng, by = c("CONTINENT" = "Drzava_drzavljanstva"))) +
  geom_polygon(data = evropa %>% filter(CONTINENT == "Europe"), fill = "#ADDCFF")

zemljevid.selitve.evropa <- ggplot() + aes(x = long, y = lat, group = group, fill = Stevilo) +
  geom_polygon(data = evropa %>% filter(CONTINENT == "Europe" |
                                          SOVEREIGNT %in% c("Canada",
                                                            "United States of America")) %>%
                 left_join(selitve.eng, by = c("SOVEREIGNT" = "Drzava_drzavljanstva"))) +
  coord_cartesian(xlim = c(-70, 35), ylim = c(35, 70))

Da bo pravilno prikazalo podatke, AVSTRALIJA IN OCEANIJA prevajaj kot Oceania, nizov Druge države ... pa ne prevajaj (prav tako ni potrebe po prevajanju Neznana država - to bo postalo NA in se ne bo nikjer prikazalo). Pri Bosnia in Herzegovina imaš na koncu še presledek - odstrani ga, da ti bo tudi to državo ustrezno pobarvalo.

Sicer pa očitno podatkov za razpredelnico tabela2 ne bereš v celoti - v funkciji uvozi2 pri read_csv2 podaj parameter n_max = 75. Da ne bo potrebno izven funkcije popravljati tipa stolpca Stevilo, pri mutate namesto samo Stevilo podaj Stevilo = parse_number(Stevilo, na = "...").

Za html2 pa svetujem, da si datoteko HTML shraniš v mapo podatki, tako kot imaš za html1.

HovnikK15 commented 6 years ago

Pozdavljeni, imam še par vprašanj pri tabeli html2 sem poskušal odstraniti pike pred imenom države, a žal neuspešno. Mi lahko prosim pomagate. Prav tako bi rad ime Evropa skupaj zamenjal s samo Evropa, da mi bo potem delalo tu tudi na zemljevidu. Najlepša hvala

HovnikK15 commented 6 years ago

Aja, pa če se da, bi morda rad naredil desno (oz. zgornjo, zraven osi) poravnavo besedila na x osi, za lažjo preglednost. Vendar tudi nisem našel ustrezne funkcije, ki bi delovala

jaanos commented 6 years ago

Takole bi šlo:

  tabhtml$Drzava_prihodnjega_prebivalisca <- gsub("^[.]*", "",
                                                  tabhtml$Drzava_prihodnjega_prebivalisca)
  tabhtml$Drzava_prihodnjega_prebivalisca <- gsub("EVROPA - SKUPAJ", "EVROPA",
                                                  tabhtml$Drzava_prihodnjega_prebivalisca)

Pika namreč v regularnih izrazih pomeni katerikoli znak, zato jo je treba drugače podati. V kontekstu oglatih oklepajev tega pomena nima, zato jo lahko iščeš na ta način (druga možnost bi bila, da pred njo postaviš \ - ker je ta poseben znak že v R-jevih nizih, bi ga bilo potrebno podvojiti). Zgornji ukaz torej išče poljubno število pik na začetku niza in jih nadomesti s praznim nizom.

Poravnavo besedila lahko kontroliraš s parametrom hjust pri element_text - 0 pomeni levo poravnavo, 1 pa desno. Sicer pa pri graf4 pazi, da za vsako državo narišeš samo en podatek - v tabela2 imaš podatke za vsako leto in spol, tako da jih bo potrebno npr. sešteti. Koristno bo tudi, da države urediš glede na prikazano vrednost - to lahko dosežeš s funkcijo reorder:

graf4 <- ggplot(tabela2 %>%
                  filter(Vrsta_migrantov == "Priseljeni iz tujine",
                         Drzava_drzavljanstva != "EVROPA",
                         Drzava_drzavljanstva != "SEVERNA IN SREDNJA AMERIKA") %>%
                  group_by(Drzava_drzavljanstva) %>%
                  summarise(Stevilo = sum(Stevilo, na.rm = TRUE)),
                aes(x = reorder(Drzava_drzavljanstva, -Stevilo), y = Stevilo)) +
  geom_bar(stat = "identity", position = "dodge", fill = "purple") +
  xlab("Država državljanstva") + ylab("Število") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) +
  ggtitle("Število preselitev iz posameznih držav v Slovenijo")
jaanos commented 6 years ago

Še to: opažam, da trenutno dobiš napako pri zadnjih dveh zemljevidih. Stolpec, po katerem združuješ, bo treba zamenjati z Drzava_prihodnjega_prebivalisca.

HovnikK15 commented 6 years ago

Še par zadnjih vprašanj. pri grafu graf5, bi rad, da bi se v poročilu prikazal večje (zaradi zelo velikega opisa na x osi, se podatki na grafu sploh ne prikažejo razen ko klikneš zoom- ampak to v poročilu ni mogoče )

potem mi zadnja dva zemljevida ne prikazujeta regij s šumniki? kaj bi lahko bil problem

prav tako me zanima, če bi lahko zemljevid.selitve.evropa spremenil tako, da bi bilo podobno kot pri celinah, Bosna in Hercegovina izvzeta iz legende, da bi bil zemljevid malo bol pregleden (zdaj skoraj vse države v podobnem odtenku) Pa še nekaj, pri nekaterih zemljevidih imam kar skopirano od prejšnjega zemljevida, ki ste mi ga vi popravili filter(Continent = Evropa| soverign.. Canada..) ali je to potrebno oz kako naj to spremenim, če ni, da bi vseeno delovalo.

jaanos commented 6 years ago

Svetujem, da pri graf5 zamenjaš oznake s krajšimi, npr.

graf5 + scale_x_discrete(labels = c("Gradbeništvo",
                                    "Predelovalne",
                                    "Promet",
                                    ...))

Lahko pa tudi narediš nekakšen šifrant in ga pojasniš v poročilu. Tako lahko podaš parameter labels = sapply(1:21 + 64, intToUtf8), pa bodo oznake postale črke od A do U (v tem primeru bi bilo smiselno odstraniti rotacijo).

Na zemljevidu Slovenije ti ne prikaže dveh regij, ki imajo v podatkih drugačno ime. Najlažje bo, če imena spremeniš kar v zemljevidu:

levels(zemljevid$NAME_1)[levels(zemljevid$NAME_1) %in%
                           c("Notranjsko-kraška",
                             "Spodnjeposavska")] <- c("Primorsko-kraška",
                                                      "Posavska")

BiH izvzameš iz zemljevida na podoben način kot pri zemljevidu celin, npr.

zemljevid.selitve.evropa <- ggplot() + aes(x = long, y = lat, group = group, fill = Stevilo) +
  geom_polygon(data = evropa %>% filter(CONTINENT == "Europe",
                                        SOVEREIGNT != "Bosnia and Herzegovina") %>%
                 left_join(selitve.eng, by = c("SOVEREIGNT" = "Drzava_drzavljanstva"))) +
  geom_polygon(data = evropa %>% filter(SOVEREIGNT == "Bosnia and Herzegovina"), fill = "#ADDCFF") +
  coord_cartesian(xlim = c(-25, 35), ylim = c(35, 70)) + 
  ggtitle("Število priselitev iz posameznih držav")

Večina Evrope sicer ostaja v podobnem odtenku, se pa vsaj vidijo razlike za države bivše Jugoslavije.

Če prikazuješ samo Evropo, seveda ni potrebno posebej vključevati ZDA in Kanade - tako kot zgoraj.

Glede na to, da ti zdaj poročilo prevede, bom posodobil povezavo na repoztoriju za zagovore na trenutni commit. Če boš še kaj spreminjal in boš želel posodobiti povezavo, odpri issue na repozitoriju za zagovore (glej navodila spodaj).

HovnikK15 commented 6 years ago

Pozdravljeni, še vedno imam težavo glede regij v zemljevidu. Vaše kode nisem znal vstaviti v svojo, zato sem sam poskusil. če zapišem zelo zamudno kodo kjer obema regijama, ki ne delujeta zapišem novo ime, vsem ostalim pa enako. vse deluje če pa bi želel z uporabo funkcije gsub pa zadeva ne deluje za Primorsko-kraško regijo, prav tako pa se pojavi napaka, da ne prikaže Koroške. Prav tako mi je čudno, zakaj mi brez uvedbe novih imen za vse regije (tako kot pri prvi možnosti) ne prikaže Obalne in Goriške regije.

potem pa me zanima par informacij glede shiny-a. Nimam sploh idej niti nekega uporabnega vzorca kako sploh začeti. Kaj svetujete? hvala in lep pozdrav

jaanos commented 6 years ago

Če prav razumem, ti sedaj deluje zemljevid zemljevid.odselitve.slo. Meni sicer deluje tudi zemljevid.odselitve.slo1, a bo v redu tudi prva možnost. Kar lahko sicer narediš je to, da ne navajaš nespremenjenih imen, in jih potem tudi v podatkih ne spremeniš:

ime_regije <- c("Primorsko-kraška" = "Notranjsko-kraška",
                "Posavska" = "Spodnjeposavska")

tabela3.regije <- tabela3 %>% mutate(Regija = ifelse(Regija %in% names(ime_regije),
                                                     ime_regije[Regija], Regija))

Potem lahko regije.priselitve in regije.odselitve izpelješ iz tabela3.regije, kjer so regije že preimenovane.

Mimogrede: opažam, da sedaj v poročilu dvakrat kličeš vizualizacija.r, tako da enega izmed teh klicev odstrani.

Glede Shinyja pa svetujem, da si pogledaš galerijo z različnimi primeri, kaj lahko počneš. Potem pa priredi programa server.R in ui.R v mapi shiny, da bo aplikacija izgledala, kot želiš.