ProHoster > Blogi > Haldamine > Pesastatud veergude laiendamine – loendid, mis kasutavad R-keelt (tidyr pakett ja unnesti perekonna funktsioonid)
Pesastatud veergude laiendamine – loendid, mis kasutavad R-keelt (tidyr pakett ja unnesti perekonna funktsioonid)
Enamikul juhtudel, kui töötate API-lt saadud vastusega või muude keeruka puustruktuuriga andmetega, seisate silmitsi JSON- ja XML-vormingutega.
Nendel vormingutel on palju eeliseid: need salvestavad andmeid üsna kompaktselt ja võimaldavad vältida teabe tarbetut dubleerimist.
Nende vormingute puuduseks on nende töötlemise ja analüüsi keerukus. Struktureerimata andmeid ei saa arvutustes kasutada ja visualiseerimist ei saa sellele üles ehitada.
See artikkel on väljaande loogiline jätk "R-pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider". See aitab teil paketti kasutades tuua struktureerimata andmestruktuure tuttavasse ja analüüsimiseks sobivasse tabelivormi tidyr, mis sisaldub raamatukogu tuumas tidyverseja selle funktsioonide perekond unnest_*().
Sisu
Kui olete huvitatud andmete analüüsist, võite olla huvitatud minu telegramm и youtube kanalid. Suurem osa sisust on pühendatud R-keelele.
Ristkülikukujundamine(Tõlkija märkus, et ma ei leidnud selle termini jaoks sobivaid tõlkevõimalusi, seega jätame selle nii, nagu see on.) on protsess, mille käigus tuuakse pesastatud massiividega struktureerimata andmed kahemõõtmelisse tabelisse, mis koosneb tuttavatest ridadest ja veergudest. IN tidyr On mitmeid funktsioone, mis aitavad teil pesastatud loendi veerge laiendada ja andmeid ristkülikukujuliseks tabelikujuliseks muuta.
unnest_longer() võtab veergude loendi iga elemendi ja loob uue rea.
unnest_wider() võtab veergude loendi iga elemendi ja loob uue veeru.
unnest_auto() määrab automaatselt, millist funktsiooni on kõige parem kasutada unnest_longer() või unnest_wider().
hoist() sarnane unnest_wider() kuid valib ainult määratud komponendid ja võimaldab töötada mitme pesastamistasemega.
Enamiku probleemidest, mis on seotud mitme pesastustasemega struktureerimata andmete toomisega kahemõõtmelisse tabelisse, saab lahendada loetletud funktsioonide kombineerimisel dplyr-ga.
Nende tehnikate demonstreerimiseks kasutame paketti repurrrsive, mis pakub mitut keerulist mitmetasandilist loendit, mis on tuletatud veebi API-st.
Alustame gh_users, loend, mis sisaldab teavet kuue GitHubi kasutaja kohta. Esmalt muudame nimekirja gh_users в tibble raam:
users <- tibble( user = gh_users )
See tundub veidi vastuoluline: miks esitada nimekiri gh_users, keerukamale andmestruktuurile? Kuid andmeraamil on suur eelis: see ühendab mitu vektorit, nii et kõike jälgitakse ühes objektis.
Iga objekti element users on nimega loend, milles iga element tähistab veergu.
Sel juhul on meil tabel, mis koosneb 30 veerust ja me ei vaja enamikku neist, seega saame selle asemel unnest_wider() kasutage hoist(). hoist() võimaldab meil eraldada valitud komponendid, kasutades sama süntaksit nagu purrr::pluck():
users %>% hoist(user,
followers = "followers",
login = "login",
url = "html_url"
)
#> # A tibble: 6 x 4
#> followers login url user
#> <int> <chr> <chr> <list>
#> 1 303 gaborcsardi https://github.com/gaborcsardi <named list [27]>
#> 2 780 jennybc https://github.com/jennybc <named list [27]>
#> 3 3958 jtleek https://github.com/jtleek <named list [27]>
#> 4 115 juliasilge https://github.com/juliasilge <named list [27]>
#> 5 213 leeper https://github.com/leeper <named list [27]>
#> 6 34 masalmon https://github.com/masalmon <named list [27]>
hoist() eemaldab määratud nimega komponendid veergude loendist kasutajanii et võite kaaluda hoist() nagu komponentide teisaldamine kuupäevaraami sisemisest loendist selle ülemisele tasemele.
Githubi hoidlad
Loendi joondamine gh_repos alustame sarnaselt selle teisendamisega tibble:
Seekord elemendid kasutaja esindavad sellele kasutajale kuuluvate hoidlate loendit. Iga hoidla on eraldi vaatlus, seega puhaste andmete kontseptsiooni kohaselt (umbes korralikud andmed) neist peaks saama uued read, mistõttu me kasutame unnest_longer() kuid mitte unnest_wider():
repos <- repos %>% unnest_longer(repo)
repos
#> # A tibble: 176 x 1
#> repo
#> <list>
#> 1 <named list [68]>
#> 2 <named list [68]>
#> 3 <named list [68]>
#> 4 <named list [68]>
#> 5 <named list [68]>
#> 6 <named list [68]>
#> 7 <named list [68]>
#> 8 <named list [68]>
#> 9 <named list [68]>
#> 10 <named list [68]>
#> # … with 166 more rows
Nüüd saame kasutada unnest_wider() või hoist() :
repos %>% hoist(repo,
login = c("owner", "login"),
name = "name",
homepage = "homepage",
watchers = "watchers_count"
)
#> # A tibble: 176 x 5
#> login name homepage watchers repo
#> <chr> <chr> <chr> <int> <list>
#> 1 gaborcsardi after <NA> 5 <named list [65]>
#> 2 gaborcsardi argufy <NA> 19 <named list [65]>
#> 3 gaborcsardi ask <NA> 5 <named list [65]>
#> 4 gaborcsardi baseimports <NA> 0 <named list [65]>
#> 5 gaborcsardi citest <NA> 0 <named list [65]>
#> 6 gaborcsardi clisymbols "" 18 <named list [65]>
#> 7 gaborcsardi cmaker <NA> 0 <named list [65]>
#> 8 gaborcsardi cmark <NA> 0 <named list [65]>
#> 9 gaborcsardi conditions <NA> 0 <named list [65]>
#> 10 gaborcsardi crayon <NA> 52 <named list [65]>
#> # … with 166 more rows
Pöörake tähelepanu kasutamisele c("owner", "login"): see võimaldab meil saada teise taseme väärtuse pesastatud loendist owner. Alternatiivne lähenemisviis on kogu loendi hankimine owner ja seejärel funktsiooni kasutades unnest_wider() pane kõik selle elemendid veergu:
Selle asemel, et mõelda õige funktsiooni valikule unnest_longer() või unnest_wider() sa võid kasutada unnest_auto(). See funktsioon kasutab andmete teisendamiseks sobivaima funktsiooni valimiseks mitut heuristlikku meetodit ja kuvab valitud meetodi kohta teate.
got_chars sellel on identne struktuur gh_users: see on nimeliste loendite kogum, kus iga sisemise loendi element kirjeldab mõnda Troonide mängu tegelase atribuuti. Toomine got_chars Tabelivaate jaoks alustame kuupäevaraami loomisega, nagu eelmistes näidetes, ja teisendame seejärel iga elemendi eraldi veergu:
chars <- tibble(char = got_chars)
chars
#> # A tibble: 30 x 1
#> char
#> <list>
#> 1 <named list [18]>
#> 2 <named list [18]>
#> 3 <named list [18]>
#> 4 <named list [18]>
#> 5 <named list [18]>
#> 6 <named list [18]>
#> 7 <named list [18]>
#> 8 <named list [18]>
#> 9 <named list [18]>
#> 10 <named list [18]>
#> # … with 20 more rows
chars2 <- chars %>% unnest_wider(char)
chars2
#> # A tibble: 30 x 18
#> url id name gender culture born died alive titles aliases father
#> <chr> <int> <chr> <chr> <chr> <chr> <chr> <lgl> <list> <list> <chr>
#> 1 http… 1022 Theo… Male Ironbo… In 2… "" TRUE <chr … <chr [… ""
#> 2 http… 1052 Tyri… Male "" In 2… "" TRUE <chr … <chr [… ""
#> 3 http… 1074 Vict… Male Ironbo… In 2… "" TRUE <chr … <chr [… ""
#> 4 http… 1109 Will Male "" "" In 2… FALSE <chr … <chr [… ""
#> 5 http… 1166 Areo… Male Norvos… In 2… "" TRUE <chr … <chr [… ""
#> 6 http… 1267 Chett Male "" At H… In 2… FALSE <chr … <chr [… ""
#> 7 http… 1295 Cres… Male "" In 2… In 2… FALSE <chr … <chr [… ""
#> 8 http… 130 Aria… Female Dornish In 2… "" TRUE <chr … <chr [… ""
#> 9 http… 1303 Daen… Female Valyri… In 2… "" TRUE <chr … <chr [… ""
#> 10 http… 1319 Davo… Male Wester… In 2… "" TRUE <chr … <chr [… ""
#> # … with 20 more rows, and 7 more variables: mother <chr>, spouse <chr>,
#> # allegiances <list>, books <list>, povBooks <list>, tvSeries <list>,
#> # playedBy <list>
Struktuur got_chars mõnevõrra raskem kui gh_users, sest mõned loendi komponendid char ise on nimekiri, mille tulemusena saame sambad - loendid:
Teie edasised tegevused sõltuvad analüüsi eesmärkidest. Võib-olla peate lisama teabe iga raamatu ja seeria ridadele, milles tegelane esineb:
chars2 %>%
select(name, books, tvSeries) %>%
pivot_longer(c(books, tvSeries), names_to = "media", values_to = "value") %>%
unnest_longer(value)
#> # A tibble: 180 x 3
#> name media value
#> <chr> <chr> <chr>
#> 1 Theon Greyjoy books A Game of Thrones
#> 2 Theon Greyjoy books A Storm of Swords
#> 3 Theon Greyjoy books A Feast for Crows
#> 4 Theon Greyjoy tvSeries Season 1
#> 5 Theon Greyjoy tvSeries Season 2
#> 6 Theon Greyjoy tvSeries Season 3
#> 7 Theon Greyjoy tvSeries Season 4
#> 8 Theon Greyjoy tvSeries Season 5
#> 9 Theon Greyjoy tvSeries Season 6
#> 10 Tyrion Lannister books A Feast for Crows
#> # … with 170 more rows
Või äkki soovite luua tabeli, mis võimaldab teil tegelase ja teose sobitada:
chars2 %>%
select(name, title = titles) %>%
unnest_longer(title)
#> # A tibble: 60 x 2
#> name title
#> <chr> <chr>
#> 1 Theon Greyjoy Prince of Winterfell
#> 2 Theon Greyjoy Captain of Sea Bitch
#> 3 Theon Greyjoy Lord of the Iron Islands (by law of the green lands)
#> 4 Tyrion Lannister Acting Hand of the King (former)
#> 5 Tyrion Lannister Master of Coin (former)
#> 6 Victarion Greyjoy Lord Captain of the Iron Fleet
#> 7 Victarion Greyjoy Master of the Iron Victory
#> 8 Will ""
#> 9 Areo Hotah Captain of the Guard at Sunspear
#> 10 Chett ""
#> # … with 50 more rows
(Pange tähele tühjad väärtused "" valdkonnas title, on selle põhjuseks andmete sisestamisel tehtud vead got_chars: tegelikult tegelased, kelle jaoks vastavad raamatute ja telesarjade pealkirjad valdkonnas puuduvad title peab olema vektor pikkusega 0, mitte vektor pikkusega 1, mis sisaldab tühja stringi.)
Funktsiooni abil saame ülaltoodud näite ümber kirjutada unnest_auto(). See lähenemisviis on ühekordseks analüüsiks mugav, kuid te ei tohiks sellele tugineda unnest_auto() regulaarseks kasutamiseks. Asi on selles, et kui teie andmestruktuur muutub unnest_auto() saab muuta valitud andmete teisendusmehhanismi, kui see algselt laiendas loendi veerud ridadeks kasutades unnest_longer(), siis kui saabuvate andmete struktuur muutub, saab loogikat kasuks muuta unnest_wider(), ja selle lähenemisviisi pidev kasutamine võib põhjustada ootamatuid vigu.
tibble(char = got_chars) %>%
unnest_auto(char) %>%
select(name, title = titles) %>%
unnest_auto(title)
#> Using `unnest_wider(char)`; elements have 18 names in common
#> Using `unnest_longer(title)`; no element has names
#> # A tibble: 60 x 2
#> name title
#> <chr> <chr>
#> 1 Theon Greyjoy Prince of Winterfell
#> 2 Theon Greyjoy Captain of Sea Bitch
#> 3 Theon Greyjoy Lord of the Iron Islands (by law of the green lands)
#> 4 Tyrion Lannister Acting Hand of the King (former)
#> 5 Tyrion Lannister Master of Coin (former)
#> 6 Victarion Greyjoy Lord Captain of the Iron Fleet
#> 7 Victarion Greyjoy Master of the Iron Victory
#> 8 Will ""
#> 9 Areo Hotah Captain of the Guard at Sunspear
#> 10 Chett ""
#> # … with 50 more rows
Geokodeerimine Google'iga
Järgmisena vaatame Google'i geokodeerimisteenusest saadud andmete keerukamat struktuuri. Mandaatide vahemällu salvestamine on vastuolus Google Mapsi API-ga töötamise reeglitega, seega kirjutan esmalt API ümber lihtsa ümbrise. Mis põhineb Google Mapsi API võtme salvestamisel keskkonnamuutujas; Kui teil pole keskkonnamuutujatesse salvestatud võtit Google Mapsi API-ga töötamiseks, siis selles jaotises esitatud koodifragmente ei käivitata.
has_key <- !identical(Sys.getenv("GOOGLE_MAPS_API_KEY"), "")
if (!has_key) {
message("No Google Maps API key found; code chunks will not be run")
}
# https://developers.google.com/maps/documentation/geocoding
geocode <- function(address, api_key = Sys.getenv("GOOGLE_MAPS_API_KEY")) {
url <- "https://maps.googleapis.com/maps/api/geocode/json"
url <- paste0(url, "?address=", URLencode(address), "&key=", api_key)
jsonlite::read_json(url)
}
Selle funktsiooni tagastatav loend on üsna keeruline:
Õnneks saame funktsioonide abil samm-sammult nende andmete tabeliks teisendamise probleemi lahendada tidyr. Et ülesanne oleks pisut keerulisem ja realistlikum, alustan mõne linna geokodeerimisega:
city <- c ( "Houston" , "LA" , "New York" , "Chicago" , "Springfield" ) city_geo <- purrr::map (city, geocode)
Teisendan saadud tulemuse järgmiseks tibble, lisan mugavuse huvides veeru vastava linnanimega.
loc <- tibble(city = city, json = city_geo)
loc
#> # A tibble: 5 x 2
#> city json
#> <chr> <list>
#> 1 Houston <named list [2]>
#> 2 LA <named list [2]>
#> 3 New York <named list [2]>
#> 4 Chicago <named list [2]>
#> 5 Springfield <named list [2]>
Esimene tase sisaldab komponente status и result, millega saame laiendada unnest_wider() :
loc %>%
unnest_wider(json)
#> # A tibble: 5 x 3
#> city results status
#> <chr> <list> <chr>
#> 1 Houston <list [1]> OK
#> 2 LA <list [1]> OK
#> 3 New York <list [1]> OK
#> 4 Chicago <list [1]> OK
#> 5 Springfield <list [1]> OK
Pange tähele, et results on mitmetasandiline loend. Enamikul linnadel on 1 element (mis esindab ainulaadset väärtust, mis vastab geokodeerimise API-le), kuid Springfieldil on kaks. Me saame need tõmmata eraldi ridadeks unnest_longer() :
loc %>%
unnest_wider(json) %>%
unnest_longer(results)
#> # A tibble: 5 x 3
#> city results status
#> <chr> <list> <chr>
#> 1 Houston <named list [5]> OK
#> 2 LA <named list [5]> OK
#> 3 New York <named list [5]> OK
#> 4 Chicago <named list [5]> OK
#> 5 Springfield <named list [5]> OK
Nüüd on neil kõigil samad komponendid, mida saab kontrollida kasutades unnest_wider():
loc %>%
unnest_wider(json) %>%
unnest_longer(results) %>%
unnest_wider(results)
#> # A tibble: 5 x 7
#> city address_componen… formatted_addre… geometry place_id types status
#> <chr> <list> <chr> <list> <chr> <lis> <chr>
#> 1 Houst… <list [4]> Houston, TX, USA <named … ChIJAYWN… <lis… OK
#> 2 LA <list [4]> Los Angeles, CA… <named … ChIJE9on… <lis… OK
#> 3 New Y… <list [3]> New York, NY, U… <named … ChIJOwg_… <lis… OK
#> 4 Chica… <list [4]> Chicago, IL, USA <named … ChIJ7cv0… <lis… OK
#> 5 Sprin… <list [5]> Springfield, MO… <named … ChIJP5jI… <lis… OK
Iga linna pikkus- ja laiuskraadide koordinaadid leiame loendit laiendades geometry:
loc %>%
unnest_wider(json) %>%
unnest_longer(results) %>%
unnest_wider(results) %>%
unnest_wider(geometry)
#> # A tibble: 5 x 10
#> city address_compone… formatted_addre… bounds location location_type
#> <chr> <list> <chr> <list> <list> <chr>
#> 1 Hous… <list [4]> Houston, TX, USA <name… <named … APPROXIMATE
#> 2 LA <list [4]> Los Angeles, CA… <name… <named … APPROXIMATE
#> 3 New … <list [3]> New York, NY, U… <name… <named … APPROXIMATE
#> 4 Chic… <list [4]> Chicago, IL, USA <name… <named … APPROXIMATE
#> 5 Spri… <list [5]> Springfield, MO… <name… <named … APPROXIMATE
#> # … with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> # status <chr>
Ja siis asukoht, mille jaoks peate laienema location:
loc %>%
unnest_wider(json) %>%
unnest_longer(results) %>%
unnest_wider(results) %>%
unnest_wider(geometry) %>%
unnest_wider(location)
#> # A tibble: 5 x 11
#> city address_compone… formatted_addre… bounds lat lng location_type
#> <chr> <list> <chr> <list> <dbl> <dbl> <chr>
#> 1 Hous… <list [4]> Houston, TX, USA <name… 29.8 -95.4 APPROXIMATE
#> 2 LA <list [4]> Los Angeles, CA… <name… 34.1 -118. APPROXIMATE
#> 3 New … <list [3]> New York, NY, U… <name… 40.7 -74.0 APPROXIMATE
#> 4 Chic… <list [4]> Chicago, IL, USA <name… 41.9 -87.6 APPROXIMATE
#> 5 Spri… <list [5]> Springfield, MO… <name… 37.2 -93.3 APPROXIMATE
#> # … with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> # status <chr>
Jällegi unnest_auto() lihtsustab kirjeldatud toimingut mõningate riskidega, mis võivad olla põhjustatud sissetulevate andmete struktuuri muutmisest:
loc %>%
unnest_auto(json) %>%
unnest_auto(results) %>%
unnest_auto(results) %>%
unnest_auto(geometry) %>%
unnest_auto(location)
#> Using `unnest_wider(json)`; elements have 2 names in common
#> Using `unnest_longer(results)`; no element has names
#> Using `unnest_wider(results)`; elements have 5 names in common
#> Using `unnest_wider(geometry)`; elements have 4 names in common
#> Using `unnest_wider(location)`; elements have 2 names in common
#> # A tibble: 5 x 11
#> city address_compone… formatted_addre… bounds lat lng location_type
#> <chr> <list> <chr> <list> <dbl> <dbl> <chr>
#> 1 Hous… <list [4]> Houston, TX, USA <name… 29.8 -95.4 APPROXIMATE
#> 2 LA <list [4]> Los Angeles, CA… <name… 34.1 -118. APPROXIMATE
#> 3 New … <list [3]> New York, NY, U… <name… 40.7 -74.0 APPROXIMATE
#> 4 Chic… <list [4]> Chicago, IL, USA <name… 41.9 -87.6 APPROXIMATE
#> 5 Spri… <list [5]> Springfield, MO… <name… 37.2 -93.3 APPROXIMATE
#> # … with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> # status <chr>
Võime vaadata ka iga linna esimest aadressi:
loc %>%
unnest_wider(json) %>%
hoist(results, first_result = 1) %>%
unnest_wider(first_result) %>%
unnest_wider(geometry) %>%
unnest_wider(location)
#> # A tibble: 5 x 11
#> city address_compone… formatted_addre… bounds lat lng location_type
#> <chr> <list> <chr> <list> <dbl> <dbl> <chr>
#> 1 Hous… <list [4]> Houston, TX, USA <name… 29.8 -95.4 APPROXIMATE
#> 2 LA <list [4]> Los Angeles, CA… <name… 34.1 -118. APPROXIMATE
#> 3 New … <list [3]> New York, NY, U… <name… 40.7 -74.0 APPROXIMATE
#> 4 Chic… <list [4]> Chicago, IL, USA <name… 41.9 -87.6 APPROXIMATE
#> 5 Spri… <list [5]> Springfield, MO… <name… 37.2 -93.3 APPROXIMATE
#> # … with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> # status <chr>
Või kasutada hoist() mitmetasandilise sukeldumise jaoks, kuhu otse minna lat и lng.
loc %>%
hoist(json,
lat = list("results", 1, "geometry", "location", "lat"),
lng = list("results", 1, "geometry", "location", "lng")
)
#> # A tibble: 5 x 4
#> city lat lng json
#> <chr> <dbl> <dbl> <list>
#> 1 Houston 29.8 -95.4 <named list [2]>
#> 2 LA 34.1 -118. <named list [2]>
#> 3 New York 40.7 -74.0 <named list [2]>
#> 4 Chicago 41.9 -87.6 <named list [2]>
#> 5 Springfield 37.2 -93.3 <named list [2]>
Sharla Gelfandi diskograafia
Lõpuks vaatleme kõige keerulisemat struktuuri - Sharla Gelfandi diskograafiat. Nagu ülaltoodud näidetes, alustame loendi teisendamisest üheveeruliseks andmeraamiks ja seejärel laiendame seda nii, et iga komponent oleks eraldi veerg. Samuti teisendan veeru date_added sobivasse kuupäeva ja kellaaja vormingusse R.
discs <- tibble(disc = discog) %>%
unnest_wider(disc) %>%
mutate(date_added = as.POSIXct(strptime(date_added, "%Y-%m-%dT%H:%M:%S")))
discs
#> # A tibble: 155 x 5
#> instance_id date_added basic_information id rating
#> <int> <dttm> <list> <int> <int>
#> 1 354823933 2019-02-16 17:48:59 <named list [11]> 7496378 0
#> 2 354092601 2019-02-13 14:13:11 <named list [11]> 4490852 0
#> 3 354091476 2019-02-13 14:07:23 <named list [11]> 9827276 0
#> 4 351244906 2019-02-02 11:39:58 <named list [11]> 9769203 0
#> 5 351244801 2019-02-02 11:39:37 <named list [11]> 7237138 0
#> 6 351052065 2019-02-01 20:40:53 <named list [11]> 13117042 0
#> 7 350315345 2019-01-29 15:48:37 <named list [11]> 7113575 0
#> 8 350315103 2019-01-29 15:47:22 <named list [11]> 10540713 0
#> 9 350314507 2019-01-29 15:44:08 <named list [11]> 11260950 0
#> 10 350314047 2019-01-29 15:41:35 <named list [11]> 11726853 0
#> # … with 145 more rows
Sellel tasemel saame teavet selle kohta, millal iga plaat Sharla diskograafiasse lisati, kuid me ei näe nende plaatide kohta andmeid. Selleks peame veergu laiendama basic_information:
discs %>% unnest_wider(basic_information)
#> Column name `id` must not be duplicated.
#> Use .name_repair to specify repair.
Kahjuks saame veateate, kuna... nimekirja sees basic_information seal on samanimeline veerg basic_information. Kui selline viga ilmneb, saate selle põhjuse kiireks kindlaksmääramiseks kasutada names_repair = "unique":
Seejärel saate need vastavalt vajadusele algse andmekogumiga uuesti ühendada.
Järeldus
Raamatukogu tuumani tidyverse sisaldab palju kasulikke pakette, mida ühendab ühine andmetöötlusfilosoofia.
Selles artiklis uurisime funktsioonide perekonda unnest_*(), mille eesmärk on pesastatud loenditest elementide eraldamine. See pakett sisaldab palju muid kasulikke funktsioone, mis hõlbustavad andmete kontseptsiooni järgi teisendamist Korralikud andmed.