Paketa tidyr bĂ«nĂ« pjesĂ« nĂ« bĂ«rthamĂ«n e njĂ« prej bibliotekave mĂ« tĂ« njohura nĂ« gjuhĂ«n R â tidyverse.
Qëllimi kryesor i paketës është të sjellë të dhënat në një formë të organizuar.
Në Habrë tashmë ekziston e dedikuar për këtë paketë, por është e datuar në vitin 2015. Unë dua të flas për ndryshimet më të rëndësishme, për të cilat autori i saj, Hadley Wickham, njoftoi para disa ditësh.

SJK: A do të konsiderohen funksionet gather() dhe spread() të vjetra?
Hadley Wickham: Në një farë mënyre. Ne do të ndalojmë rekomandimin e përdorimit të këtyre funksioneve dhe do të ndalojmë rregullimin e gabimeve në to, por ato do të vazhdojnë të jenë të pranishme në paketë në gjendjen aktuale.
Përmbajtja
Nëse jeni të interesuar për analizën e të dhënave, ndoshta do t'ju interesojnë kanalet e mia dhe Shumica e përmbajtjes së tyre është e dedikuar gjuhës R.
Koncepti TidyData
QĂ«llimi tidyr â pĂ«r t'ju ndihmuar tĂ« sjellni tĂ« dhĂ«nat nĂ« njĂ« formĂ« tĂ« organizuar. TĂ« dhĂ«nat e organizuara janĂ« ato ku:
- Ădo variabĂ«l Ă«shtĂ« nĂ« njĂ« kolonĂ«.
- Ădo vĂ«zhgim Ă«shtĂ« njĂ« rresht.
- Ădo vlerĂ« Ă«shtĂ« njĂ« celul.
Me të dhënat që janë sjellë në formën tidy data, është shumë më e lehtë të punoni gjatë analizes.
Funksionet kryesore që përfshihen në paketën tidyr
tidyr përmban një grup funksionesh të dizajnuara për transformimin e tabelave:
fill()â mbushja e vlerave tĂ« humbura nĂ« kolonĂ« me vlerat pĂ«rpara;separate()â ndan njĂ« fushĂ« nĂ« disa nĂ«pĂ«rmjet ndarĂ«sit;unite()â bĂ«n operacionin e bashkimit tĂ« disa fushave nĂ« njĂ«, njĂ« veprim i kundĂ«rt me funksioninseparate();pivot_longer()â funksioni qĂ« transformon tĂ« dhĂ«nat nga formati i gjerĂ« nĂ« tĂ« gjatĂ«;pivot_wider()â funksioni qĂ« transformon tĂ« dhĂ«nat nga formati i gjatĂ« nĂ« tĂ« gjerĂ«. Operacioni i kundĂ«rt i asaj qĂ« bĂ«n funksionipivot_longer().gather()i vjetruar â funksioni qĂ« transformon tĂ« dhĂ«nat nga formati i gjerĂ« nĂ« tĂ« gjatĂ«;spread()i vjetruar â funksioni qĂ« transformon tĂ« dhĂ«nat nga formati i gjatĂ« nĂ« tĂ« gjerĂ«. Operacioni i kundĂ«rt i asaj qĂ« bĂ«n funksionigather().
Një koncept i ri për transformimin e të dhënave nga formati i gjerë në të gjatë dhe anasjelltas
Më parë për këtë lloj transformimi ishin përdorur funksionet gather() dhe spread(). Në vitet e ekzistencës së këtyre funksioneve, është bërë e qartë se për shumicën e përdoruesve, përfshirë autorin e paketës, emrat e këtyre funksioneve dhe argumenteve të tyre ishin mjaft të paqarta, duke shkaktuar vështirësi në kërkimin dhe kuptimin se cili nga këto funksione sillte frame-in e të dhënave nga formati i gjerë në të gjatë dhe anasjelltas.
Për këtë arsye, në tidyr janë shtuar dy funksione të reja, të rëndësishme, të dizajnuara për transformimin e frame-ve të të dhënave.
Funkcionet e reja pivot_longer() dhe pivot_wider() kanë qenë të frymëzuar nga disa funksione nga paketa cdata, e krijuar nga John Mount dhe Nina Zumel.
Instaloni versionin më të fundit të tidyr 0.8.3.9000
Për të instaluar versionin e ri, më të fundit të paketës tidyr 0.8.3.9000, në të cilin funksionet e reja janë të disponueshme, përdorni kodin e mëposhtëm.
devtools::install_github("tidyverse/tidyr")
Në kohën e shkrimit të këtij artikulli, këto funksione janë të disponueshme vetëm në versionin dev të paketës në GitHub.
Kalim në funksionet e reja
Në të vërtetë, të kalosh skriptet e vjetra për të punuar me funksionet e reja nuk është e vështirë; për më shumë kuptim, do të marr një shembull nga dokumentacioni i funksioneve të vjetra dhe do të tregoj si këto operacione kryhen me ndihmën e titujve të rinj pivot_*() funksione.
Transformimi i formatit të gjerë në të gjatë.
Shembulli i kodit nga dokumentacioni i funksionit gather
# example
library(dplyr)
stocks <- data.frame(
time = as.Date('2009-01-01') + 0:9,
X = rnorm(10, 0, 1),
Y = rnorm(10, 0, 2),
Z = rnorm(10, 0, 4)
)
# old
stocks_gather <- stocks %>% gather(key = stock,
value = price,
-time)
# new
stocks_long <- stocks %>% pivot_longer(cols = -time,
names_to = "stock",
values_to = "price")
Transformimi i formatit të gjatë në të gjerë.
Shembulli i kodit nga dokumentacioni i funksionit spread
# old
stocks_spread <- stocks_gather %>% spread(key = stock,
value = price)
# new
stock_wide <- stocks_long %>% pivot_wider(names_from = "stock",
values_from = "price")
Duke qenë se në shembujt e mësipërm të punës me pivot_longer() dhe pivot_wider(), në tabelën e origjinës stocks nuk ka kolonash të përmendura në argumentet names_to dhe values_to emrat e tyre duhet të përcaktohen në thonjëza.
Tabela me të cilën do t'ju jetë më e lehtë të kuptoni se si të kaloni në punën me konceptin e ri tidyr.

Vërejtje nga autori
I gjithë teksti i mëpasshëm është një përkthim adaptiv, madje mund ta quaja përkthim të lirë nga faqja zyrtare e bibliotekës tidyverse.
Një shembull i thjeshtë i transformimit të të dhënave nga formati i gjerë në të gjatë
pivot_longer () â bĂ«n setet e tĂ« dhĂ«nave mĂ« tĂ« gjatĂ«, duke reduktuar numrin e kolonnave dhe duke rritur numrin e rreshtave.

Për të realizuar shembujt e paraqitur në artikull, fillimisht është e nevojshme të ngarkoni paketat e nevojshme:
library(tidyr)
library(dplyr)
library(readr)Le të supozojmë se kemi një tabelë me rezultatet e një ankete, në të cilën (ndër të tjera) iu kërkua njerëzve për besimin e tyre dhe të ardhurat e tyre vjetore:
#> # A tibble: 18 x 11
#> religion `<$10k` `$10-20k` `$20-30k` `$30-40k` `$40-50k` `$50-75k`
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Agnostic 27 34 60 81 76 137
#> 2 Atheist 12 27 37 52 35 70
#> 3 Buddhist 27 21 30 34 33 58
#> 4 Catholic 418 617 732 670 638 1116
#> 5 Donât k⊠15 14 15 11 10 35
#> 6 Evangel⊠575 869 1064 982 881 1486
#> 7 Hindu 1 9 7 9 11 34
#> 8 Histori⊠228 244 236 238 197 223
#> 9 Jehovah⊠20 27 24 24 21 30
#> 10 Jewish 19 19 25 25 30 95
#> # ⊠with 8 more rows, and 4 more variables: `$75-100k` <dbl>,
#> # `$100-150k` <dbl>, `>150k` <dbl>, `Don't know/refused` <dbl>Ky tabela përmban të dhëna mbi fenë e respondentëve në rreshta, ndërsa nivelet e të ardhurave janë shpërndarë në emrat e kolonave. Numri i respondentëve nga çdo kategori ruhet në vlerat e qelizave në ndërthyerjen e fesë dhe nivelit të të ardhurave. Për ta sjellë tabelën në një format të pastër dhe të saktë, mjafton të përdorni pivot_longer():
pew %>%
pivot_longer(cols = -religion, names_to = "income", values_to = "count")pew %>%
pivot_longer(cols = -religion, names_to = "income", values_to = "count")
#> # Një tibble: 180 x 3
#> religion income count
#>
#> 1 Agnostik 2 Agnostik $10-20k 34
#> 3 Agnostik $20-30k 60
#> 4 Agnostik $30-40k 81
#> 5 Agnostik $40-50k 76
#> 6 Agnostik $50-75k 137
#> 7 Agnostik $75-100k 122
#> 8 Agnostik $100-150k 109
#> 9 Agnostik >150k 84
#> 10 Agnostik Nuk e di/refuzuar 96
#> # ⊠me 170 rreshta të tjeraArgumentet e funksionit pivot_longer()
- Argumenti i parë cols, përshkruan, cilat kolona duhet të bashkohen. Në këtë rast, të gjitha kolonat, përveç time.
- Argumenti names_to i jep emrin e variablit që do të krijohet nga emrat e kolonave që kemi bashkuar.
- values_to i jep emrin e variablit që do të krijohet nga të dhënat që ruhen në vlerat e qelizave të kolonave të bashkuara.
Specifikimet
Ky është një funksionalitet i ri i paketës tidyr, i cili më parë, duke punuar me funksione të vjetruara, nuk ishte në dispozicion.
Specifikimi është një kadër të dhënash, çdo rresht i të cilit i përkon një kolone në kadrin e të dhënave të reja, si dhe dy kolona speciale që fillojnë me:
- .emër përmban emrin origjinal të kolonës.
- .value përmban emrin e kolonës, në të cilën do të futen vlerat e qelizave.
Kolonat e tjera të specifikimit pasqyrojnë se si do të shfaqet emri i kolonave të kompresuara në .emër.
Specifikimi përshkruan metadata që ruhen në emrin e kolonës, me një rresht për çdo kolonë dhe një kolone për çdo variabël të bashkuar me emrin e kolonës, ndoshta tani ky përkufizim duket i ndërlikuar, por pas shqyrtimit të disa shembujve gjithçka do të bëhet shumë më e qartë.
Kërkesa e specifikimit është që ju mund të nxirrni, modifikoni dhe vendosni metadata të reja për kadrin e të dhënave të transformuar.
Për të punuar me specifikacione kur transformoni tabelën nga formati i gjerë në të gjatë, shërben funksioni pivot_longer_spec().
Si funksionon ky funksion, ai merr çdo kadrin e të dhënave dhe formon metadatën e tij në mënyrën e përshkruar më sipër.
Për shembull, le të marrim grupin e të dhënave që ofrohet me paketën tidyr. Ky grup të dhënash përmban informacion të ofruar nga Organizata Botërore e Shëndetësisë mbi sëmundshmërinë e tuberkulozit.
who
#> # Një tibble: 7,240 x 60
#> country iso2 iso3 year new_sp_m014 new_sp_m1524 new_sp_m2534
#> <chr> <int> <int> <int> <int>
#> 1 Afghan⊠AF AFG 1980 NA NA NA
#> 2 Afghan⊠AF AFG 1981 NA NA NA
#> 3 Afghan⊠AF AFG 1982 NA NA NA
#> 4 Afghan⊠AF AFG 1983 NA NA NA
#> 5 Afghan⊠AF AFG 1984 NA NA NA
#> 6 Afghan⊠AF AFG 1985 NA NA NA
#> 7 Afghan⊠AF AFG 1986 NA NA NA
#> 8 Afghan⊠AF AFG 1987 NA NA NA
#> 9 Afghan⊠AF AFG 1988 NA NA NA
#> 10 Afghan⊠AF AFG 1989 NA NA NA
#> # ⊠me 7,230 rreshta të tjera, dhe 53 variabla të tjerëLe ta nisim specifikimin e tij.
spec %
pivot_longer_spec(new_sp_m014:newrel_f65, values_to = "count")#> # A tibble: 56 x 3
#> .name .value name
#> <chr> <chr> <chr>
#> 1 new_sp_m014 count new_sp_m014
#> 2 new_sp_m1524 count new_sp_m1524
#> 3 new_sp_m2534 count new_sp_m2534
#> 4 new_sp_m3544 count new_sp_m3544
#> 5 new_sp_m4554 count new_sp_m4554
#> 6 new_sp_m5564 count new_sp_m5564
#> 7 new_sp_m65 count new_sp_m65
#> 8 new_sp_f014 count new_sp_f014
#> 9 new_sp_f1524 count new_sp_f1524
#> 10 new_sp_f2534 count new_sp_f2534
#> # ⊠with 46 more rowsFushat country, iso2, iso3 tani që janë variabla. Detyra jonë është të përmbysim kolonat me new_sp_m014 për newrel_f65.
Në emrat e këtyre kolonave ruhet informacioni në vijim:
- Prefiksi
new_tregon se përmban të dhëna mbi rastet e reja të sëmundjes së tuberkulozit, modeli i tanishëm i të dhënave përmban informacion vetëm për rastet e reja, prandaj ky prefiks nuk ka asnjë përcaktim në këtë kontekst. sp/rel/sp/eppërshkruan metodën e diagnozës së sëmundjes.m/fgjinia e pacientit.014/1524/2535/3544/4554/65grupi moshor i pacientit.
Ne mund të ndajmë këto kolona duke përdorur funksionin extract(), duke përdorur shprehjen e rregullt.
spec %
extract(name, c("diagnosis", "gender", "age"), "new_?(.*)_(.)(.*)")#> # A tibble: 56 x 5
#> .name .value diagnosis gender age
#> <chr> <chr> <chr> <chr> <chr>
#> 1 new_sp_m014 count sp m 014
#> 2 new_sp_m1524 count sp m 1524
#> 3 new_sp_m2534 count sp m 2534
#> 4 new_sp_m3544 count sp m 3544
#> 5 new_sp_m4554 count sp m 4554
#> 6 new_sp_m5564 count sp m 5564
#> 7 new_sp_m65 count sp m 65
#> 8 new_sp_f014 count sp f 014
#> 9 new_sp_f1524 count sp f 1524
#> 10 new_sp_f2534 count sp f 2534
#> # ⊠with 46 more rowsVini re, kolona .emër duhet të mbetet e pandryshuar, pasi është indeksi ynë në emrat e kolonave të grupit të të dhënave origjinale.
Gjinia dhe mosha (kolonat gender dhe age) kanë vlera fikse dhe të njohura, prandaj është e rekomandueshme t'i transformojmë këto kolona në faktorë:
spec %
mutate(
gender = factor(gender, levels = c("f", "m")),
age = factor(age, levels = unique(age), ordered = TRUE)
) Në fund, për të aplikuar specifikimin që krijuam në kadrin tonë të të dhënave who na nevojitet të përdorim argumentin spec në funksionin pivot_longer().
who %>% pivot_longer(spec = spec)
#> # A tibble: 405,440 x 8
#> country iso2 iso3 year diagnosis gender age count
#> <chr> <chr> <chr> <int> <chr> <fct> <ord> <int>
#> 1 Afghanistan AF AFG 1980 sp m 014 NA
#> 2 Afghanistan AF AFG 1980 sp m 1524 NA
#> 3 Afghanistan AF AFG 1980 sp m 2534 NA
#> 4 Afghanistan AF AFG 1980 sp m 3544 NA
#> 5 Afghanistan AF AFG 1980 sp m 4554 NA
#> 6 Afghanistan AF AFG 1980 sp m 5564 NA
#> 7 Afghanistan AF AFG 1980 sp m 65 NA
#> 8 Afghanistan AF AFG 1980 sp f 014 NA
#> 9 Afghanistan AF AFG 1980 sp f 1524 NA
#> 10 Afghanistan AF AFG 1980 sp f 2534 NA
#> # ⊠with 405,430 more rowsGjithçka që sapo bëmë mund të ilustrohet në këtë mënyrë:

Specifikimi duke përdorur disa vlera (.value)
Në shembullin e mësipërm, kolona e specifikimit .value përmbante vetëm një vlerë, në shumicën e rasteve kështu ndodh.
Por ndodhin herë pas here situata kur është e nevojshme të mblidhen të dhëna nga kolona me tipe të ndryshme të të dhënave. Me funksionin e vjetruar, spread() do të ishte mjaft e vështirë ta bënit këtë.
Shembulli i mëposhtëm është marrë nga në paketën data.table.
Le të krijojmë një dataframe për trajnimin.
family <- tibble::tribble(
~family, ~dob_child1, ~dob_child2, ~gender_child1, ~gender_child2,
1L, "1998-11-26", "2000-01-29", 1L, 2L,
2L, "1996-06-22", NA, 2L, NA,
3L, "2002-07-11", "2004-04-05", 2L, 2L,
4L, "2004-10-10", "2009-08-27", 1L, 1L,
5L, "2000-12-05", "2005-02-28", 2L, 1L,
)
family % mutate_at(vars(starts_with("dob")), parse_date)#> # A tibble: 5 x 5
#> family dob_child1 dob_child2 gender_child1 gender_child2
#> <int> <date> <date> <int> <int>
#> 1 1 1998-11-26 2000-01-29 1 2
#> 2 2 1996-06-22 NA 2 NA
#> 3 3 2002-07-11 2004-04-05 2 2
#> 4 4 2004-10-10 2009-08-27 1 1
#> 5 5 2000-12-05 2005-02-28 2 1Dataframe i krijuar në çdo rresht përmban të dhënat për fëmijët e një familjeje. Në familje mund të ketë një ose dy fëmijë. Për secilin fëmijë ofrohen të dhëna për datën e lindjes dhe gjininë, ku të dhënat për secilin fëmijë janë në kolona të ndara; detyra jonë është t'i sjellim këto të dhëna në formatin e duhur për analizë.
Vini re se kemi dy variabla me informacion për çdo fëmijë: gjinia dhe data e lindjes (kolonat me prefiksin dop përmbajnë datën e lindjes, ndërsa kolonat me prefiksin gender përmbajnë gjininë e fëmijës). Në rezultatin e pritur ato duhet të jenë në kolona të ndara. Ne mund ta bëjmë këtë duke gjeneruar një specifikim, ku kolona .value do të ketë dy vlera të ndryshme.
spec %
pivot_longer_spec(-family) %>%
separate(col = name, into = c(".value", "child"))%>%
mutate(child = parse_number(child))
#> # A tibble: 4 x 3
#> .name .value child
#> <chr> <chr> <dbl>
#> 1 dob_child1 dob 1
#> 2 dob_child2 dob 2
#> 3 gender_child1 gender 1
#> 4 gender_child2 gender 2Tani le të shqyrtojmë hap pas hapi veprimet që kryhen nga kodi i mësipërm.
pivot_longer_spec(-family)â krijon njĂ« specifikim qĂ« ngushton tĂ« gjitha kolonat e disponueshme, pĂ«rveç kolonĂ«s family.separate(col = name, into = c(".value", "child"))â ndan kolonĂ«n .emĂ«r, e cila pĂ«rmban emrat e fushave origjinale, sipas nĂ«nvizĂ«s dhe regjistron vlerat e marra nĂ« kolona. .value dhe child.mutate(child = parse_number(child))â konverton vlerat e fushĂ«s child nga tipin tekstual nĂ« tipin numerik.
Tani ne mund të aplikojmë specifikimin e marrë në dataframe origjinal dhe ta sjellim tabelën në formatin e dëshiruar.
family %>%
pivot_longer(spec = spec, na.rm = T)#> # A tibble: 9 x 4
#> family child dob gender
#> <int> <dbl> <date> <int>
#> 1 1 1 1998-11-26 1
#> 2 1 2 2000-01-29 2
#> 3 2 1 1996-06-22 2
#> 4 3 1 2002-07-11 2
#> 5 3 2 2004-04-05 2
#> 6 4 1 2004-10-10 1
#> 7 4 2 2009-08-27 1
#> 8 5 1 2000-12-05 2
#> 9 5 2 2005-02-28 1Ne përdorim argumentin na.rm = TRUE, sepse forma aktuale e të dhënave e detyron të krijojmë rreshta të panevojshëm për vëzhgimet që nuk ekzistojnë. Meqenëse familja 2 ka vetëm një fëmijë, na.rm = TRUE siguron që familja 2 do të ketë një rresht në të dhënat e daljes.
Transformimi i frame-ve të të dhënave nga formati i gjatë në të gjerë
pivot_wider() â Ă«shtĂ« njĂ« transformim nĂ« tĂ« kundĂ«rt, dhe pĂ«rkundrazi rrit numrin e kolonave tĂ« dataframe-it duke zvogĂ«luar numrin e rreshtave.

Ky lloj transformimi është jashtëzakonisht i rrallë për të sjellë të dhënat në një pamje të pastër, megjithatë ky teknik mund të jetë i dobishëm për të krijuar tabela përmbledhëse që përdoren në prezantime, ose për integrimin me mjete të tjera.
Në të vërtetë, funksionet pivot_longer() dhe pivot_wider() janë simetrike dhe ushtrojnë veprime të kundërta ndaj njëri-tjetrit, pra: df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) dhe df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) do të kthejë df-në origjinale.
Shembulli më i thjeshtë i sjelljes së një tabele në format të gjerë
Për të demonstruar funksionimin e funksionit pivot_wider() ne do të përdorim të dhënat fish_encounters, e cila ruan informacion mbi atë se si stacionet e ndryshme regjistrojnë lëvizjen e peshqve në lum.
#> # A tibble: 114 x 3
#> fish station seen
#> <fct> <fct> <int>
#> 1 4842 Release 1
#> 2 4842 I80_1 1
#> 3 4842 Lisbon 1
#> 4 4842 Rstr 1
#> 5 4842 Base_TD 1
#> 6 4842 BCE 1
#> 7 4842 BCW 1
#> 8 4842 BCE2 1
#> 9 4842 BCW2 1
#> 10 4842 MAE 1
#> # ⊠with 104 more rowsNë shumicën e rasteve, kjo tabelë do të jetë më informative dhe e lehtë për t'u përdorur nëse paraqesim informacionin për çdo stacion në një kolonë të veçantë.
fish_encounters %>% pivot_wider(names_from = station, values_from = seen)
fish_encounters %>% pivot_wider(names_from = station, values_from = seen)
#> # A tibble: 19 x 12
#> fish Release I80_1 Lisbon Rstr Base_TD BCE BCW BCE2 BCW2 MAE
#> & & & & & & &
#> 1 4842 1 1 1 1 1 1 1 1 1 1
#> 2 4843 1 1 1 1 1 1 1 1 1 1
#> 3 4844 1 1 1 1 1 1 1 1 1 1
#> 4 4845 1 1 1 1 1 NA NA NA NA NA
#> 5 4847 1 1 1 NA NA NA NA NA NA NA
#> 6 4848 1 1 1 1 NA NA NA NA NA NA
#> 7 4849 1 1 NA NA NA NA NA NA NA NA
#> 8 4850 1 1 NA 1 1 1 1 NA NA NA
#> 9 4851 1 1 NA NA NA NA NA NA NA NA
#> 10 4854 1 1 NA NA NA NA NA NA NA NA
#> # ⊠me 9 rreshta më shumë dhe 1 variabël më shumë: MAWKy set të dhënash regjistron informacion vetëm kur peshku është konstatuar nga stacioni, pra nëse ndonjë peshk nuk është regjistruar nga ndonjë stacion, atëherë këto të dhëna nuk do të jenë në tabelë. Kjo do të thotë se të dhënat e daljes do të mbushen me NA.
Megjithatë, në këtë rast ne e dimë se mungesa e regjistrimit do të thotë që peshku nuk është bërë i dukshëm, kështu që mund të përdorim argumentin values_fill në funksionin pivot_wider() dhe të mbushim këto vlera të humbura me zero:
fish_encounters %>% pivot_wider(
names_from = station,
values_from = seen,
values_fill = list(seen = 0)
)#> # A tibble: 19 x 12
#> fish Release I80_1 Lisbon Rstr Base_TD BCE BCW BCE2 BCW2 MAE
#> <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#> 1 4842 1 1 1 1 1 1 1 1 1 1
#> 2 4843 1 1 1 1 1 1 1 1 1 1
#> 3 4844 1 1 1 1 1 1 1 1 1 1
#> 4 4845 1 1 1 1 1 0 0 0 0 0
#> 5 4847 1 1 1 0 0 0 0 0 0 0
#> 6 4848 1 1 1 1 0 0 0 0 0 0
#> 7 4849 1 1 0 0 0 0 0 0 0 0
#> 8 4850 1 1 0 1 1 1 1 0 0 0
#> 9 4851 1 1 0 0 0 0 0 0 0 0
#> 10 4854 1 1 0 0 0 0 0 0 0 0
#> # ⊠with 9 more rows, and 1 more variable: MAW <int>Gjenerimi i emrit të kolonës nga disa variabla burimorë
Imagjinoni që kemi një tabelë që përmban kombinime produkti, shteti dhe viti. Për të gjeneruar një data frame testues, mund të ekzekutoni këtë kod:
df %
filter((product == "A" & country == "AI") | product == "B") %>%
mutate(value = rnorm(nrow(.)))#> # A tibble: 45 x 4
#> product country year value
#> <chr> <chr> <int> <dbl>
#> 1 A AI 2000 -2.05
#> 2 A AI 2001 -0.676
#> 3 A AI 2002 1.60
#> 4 A AI 2003 -0.353
#> 5 A AI 2004 -0.00530
#> 6 A AI 2005 0.442
#> 7 A AI 2006 -0.610
#> 8 A AI 2007 -2.77
#> 9 A AI 2008 0.899
#> 10 A AI 2009 -0.106
#> # ⊠with 35 more rowsDetyra jonë është të zgjeronim data frame-in ndërsa një kolonë të përmbante të dhënat për çdo kombinim produkti dhe shteti. Për këtë, mjafton të kaloni në argumentin names_from një vektor që përmban emrat e fushave që do të bashkohen.
df %>% pivot_wider(names_from = c(product, country),
values_from = "value")#> # A tibble: 15 x 4
#> year A_AI B_AI B_EI
#> <int> <dbl> <dbl> <dbl>
#> 1 2000 -2.05 0.607 1.20
#> 2 2001 -0.676 1.65 -0.114
#> 3 2002 1.60 -0.0245 0.501
#> 4 2003 -0.353 1.30 -0.459
#> 5 2004 -0.00530 0.921 -0.0589
#> 6 2005 0.442 -1.55 0.594
#> 7 2006 -0.610 0.380 -1.28
#> 8 2007 -2.77 0.830 0.637
#> 9 2008 0.899 0.0175 -1.30
#> 10 2009 -0.106 -0.195 1.03
#> # ⊠with 5 more rowsGjashtas mund të aplikoni specifikime në funksionin pivot_wider(). Por në parashqitjen e pivot_wider() specifikimi bën një transformim të kundërt pivot_longer(): krijohen kolonat e përmendur në .emër, duke përdorur vlerat nga .value dhe kolonat e tjera.
Për këtë set të dhënash, mund të gjeneroni një specifikim të personalizuar nëse dëshironi që çdo kombinim të mundshëm të shtetit dhe produktit të ketë kolonë të vetën, jo vetëm ato që janë të pranishme në të dhëna:
spec %
expand(product, country, .value = "value") %>%
unite(".name", product, country, remove = FALSE)#> # A tibble: 4 x 4
#> .name product country .value
#> <chr> <chr> <chr> <chr>
#> 1 A_AI A AI value
#> 2 A_EI A EI value
#> 3 B_AI B AI value
#> 4 B_EI B EI valuedf %>% pivot_wider(spec = spec) %>% head()#> # A tibble: 6 x 5
#> year A_AI A_EI B_AI B_EI
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 2000 -2.05 NA 0.607 1.20
#> 2 2001 -0.676 NA 1.65 -0.114
#> 3 2002 1.60 NA -0.0245 0.501
#> 4 2003 -0.353 NA 1.30 -0.459
#> 5 2004 -0.00530 NA 0.921 -0.0589
#> 6 2005 0.442 NA -1.55 0.594Disa shembuj më të avancuar të punës me konceptin e ri tidyr
Shtyrja e të dhënave në një formë të organizuar me shembuj nga kompleti i të dhënave për popullsinë dhe qiradhënien në SHBA
Seti i të dhënave us_rent_income përmban informacione mbi mesataren e të ardhurave dhe qirave për çdo shtet në SHBA për vitin 2017 (seti i të dhënave është në paketën tidycensus).
us_rent_income
#> # A tibble: 104 x 5
#> GEOID NAME variable estimate moe
#>
#> 1 01 Alabama income 24476 136
#> 2 01 Alabama rent 747 3
#> 3 02 Alaska income 32940 508
#> 4 02 Alaska rent 1200 13
#> 5 04 Arizona income 27517 148
#> 6 04 Arizona rent 972 4
#> 7 05 Arkansas income 23789 165
#> 8 05 Arkansas rent 709 5
#> 9 06 California income 29454 109
#> 10 06 California rent 1358 3
#> # ⊠me 94 rreshta të tjerëNë formën e saj, siç ruhen të dhënat në datasetin us_rent_income punimi me to është ekstremisht i vështirë, prandaj do të doja të krijoja një set të dhënash me kolonat: rent, rent_moe, come, income_moe. Ekzistojnë shumë mënyra për të krijuar këtë specifikim, por e rëndësishme është që duhet të gjenerojmë çdo kombinim të vlerave të variables dhe estimate/moe, dhe më pas të krijojmë emrin e kolonës.
spec %
expand(variable, .value = c("estimate", "moe")) %>%
mutate(
.name = paste0(variable, ifelse(.value == "moe", "_moe", ""))
)#> # A tibble: 4 x 3
#> variable .value .name
#> <chr> <chr> <chr>
#> 1 income estimate income
#> 2 income moe income_moe
#> 3 rent estimate rent
#> 4 rent moe rent_moeOfrimi i këtij specifikimi pivot_wider() na jep rezultatin që kërkojmë:
us_rent_income %>% pivot_wider(spec = spec)
#> # A tibble: 52 x 6
#> GEOID NAME income income_moe rent rent_moe
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 01 Alabama 24476 136 747 3
#> 2 02 Alaska 32940 508 1200 13
#> 3 04 Arizona 27517 148 972 4
#> 4 05 Arkansas 23789 165 709 5
#> 5 06 California 29454 109 1358 3
#> 6 08 Colorado 32401 109 1125 5
#> 7 09 Connecticut 35326 195 1123 5
#> 8 10 Delaware 31560 247 1076 10
#> 9 11 District of Columbia 43198 681 1424 17
#> 10 12 Florida 25952 70 1077 3
#> # ⊠with 42 more rowsBankën Botërore
Ndonjëherë, të sjellësh setin e të dhënave në formën e duhur kërkon disa hapa.
Dataseti world_bank_pop përmban të dhëna nga banka botërore mbi popullsinë e çdo vendi në periudhën 2000 deri në 2018.
#> # A tibble: 1,056 x 20
#> country indicator `2000` `2001` `2002` `2003` `2004` `2005` `2006`
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 ABW SP.URB.T⊠4.24e4 4.30e4 4.37e4 4.42e4 4.47e+4 4.49e+4 4.49e+4
#> 2 ABW SP.URB.G⊠1.18e0 1.41e0 1.43e0 1.31e0 9.51e-1 4.91e-1 -1.78e-2
#> 3 ABW SP.POP.T⊠9.09e4 9.29e4 9.50e4 9.70e4 9.87e+4 1.00e+5 1.01e+5
#> 4 ABW SP.POP.G⊠2.06e0 2.23e0 2.23e0 2.11e0 1.76e+0 1.30e+0 7.98e-1
#> 5 AFG SP.URB.T⊠4.44e6 4.65e6 4.89e6 5.16e6 5.43e+6 5.69e+6 5.93e+6
#> 6 AFG SP.URB.G⊠3.91e0 4.66e0 5.13e0 5.23e0 5.12e+0 4.77e+0 4.12e+0
#> 7 AFG SP.POP.T⊠2.01e7 2.10e7 2.20e7 2.31e7 2.41e+7 2.51e+7 2.59e+7
#> 8 AFG SP.POP.G⊠3.49e0 4.25e0 4.72e0 4.82e0 4.47e+0 3.87e+0 3.23e+0
#> 9 AGO SP.URB.T⊠8.23e6 8.71e6 9.22e6 9.77e6 1.03e+7 1.09e+7 1.15e+7
#> 10 AGO SP.URB.G⊠5.44e0 5.59e0 5.70e0 5.76e0 5.75e+0 5.69e+0 4.92e+0
#> # ⊠with 1,046 more rows, and 11 more variables: `2007` <dbl>,
#> # `2008` <dbl>, `2009` <dbl>, `2010` <dbl>, `2011` <dbl>, `2012` <dbl>,
#> # `2013` <dbl>, `2014` <dbl>, `2015` <dbl>, `2016` <dbl>, `2017` <dbl>Qëllimi ynë është të krijojmë një set të dhënash të rregullt ku çdo variable ndodhet në një kolonë të veçantë. Deri tani, është e paqartë se cilat hapa janë të nevojshëm, por do të fillojmë me problemin më të dukshëm: viti është shpërndarë në disa kolona.
Për ta korrigjuar atë, është e nevojshme të përdoret funksioni pivot_longer().
pop2 %
pivot_longer(`2000`:`2017`, names_to = "year")#> # A tibble: 19,008 x 4
#> country indicator year value
#> <chr> <chr> <chr> <dbl>
#> 1 ABW SP.URB.TOTL 2000 42444
#> 2 ABW SP.URB.TOTL 2001 43048
#> 3 ABW SP.URB.TOTL 2002 43670
#> 4 ABW SP.URB.TOTL 2003 44246
#> 5 ABW SP.URB.TOTL 2004 44669
#> 6 ABW SP.URB.TOTL 2005 44889
#> 7 ABW SP.URB.TOTL 2006 44881
#> 8 ABW SP.URB.TOTL 2007 44686
#> 9 ABW SP.URB.TOTL 2008 44375
#> 10 ABW SP.URB.TOTL 2009 44052
#> # ⊠with 18,998 more rowsHapi tjetër është të shqyrtojmë variable-n indicator.
pop2 %>% count(indicator)
#> # A tibble: 4 x 2
#> indicator n
#> <chr> <int>
#> 1 SP.POP.GROW 4752
#> 2 SP.POP.TOTL 4752
#> 3 SP.URB.GROW 4752
#> 4 SP.URB.TOTL 4752Ku SP.POP.GROW Ă«shtĂ« rritja e popullsisĂ«, SP.POP.TOTL Ă«shtĂ« numri total i popullsisĂ«, dhe SP.URB. * Ă«shtĂ« e njĂ«jta gjĂ«, por vetĂ«m pĂ«r zonat urbane. Le tĂ« ndarim kĂ«to vlera nĂ« dy variable: area â vendi (total ose urban) dhe njĂ« variable qĂ« pĂ«rmban tĂ« dhĂ«nat efektive (population ose growth):
pop3 %
separate(indicator, c(NA, "area", "variable"))#> # A tibble: 19,008 x 5
#> country area variable year value
#> <chr> <chr> <chr> <chr> <dbl>
#> 1 ABW URB TOTL 2000 42444
#> 2 ABW URB TOTL 2001 43048
#> 3 ABW URB TOTL 2002 43670
#> 4 ABW URB TOTL 2003 44246
#> 5 ABW URB TOTL 2004 44669
#> 6 ABW URB TOTL 2005 44889
#> 7 ABW URB TOTL 2006 44881
#> 8 ABW URB TOTL 2007 44686
#> 9 ABW URB TOTL 2008 44375
#> 10 ABW URB TOTL 2009 44052
#> # ⊠with 18,998 more rowsTani na mbetet vetëm të ndajmë variable-n variable në dy kolona:
pop3 %>%
pivot_wider(names_from = variable, values_from = value)#> # A tibble: 9,504 x 5
#> country area year TOTL GROW
#> <chr> <chr> <chr> <dbl> <dbl>
#> 1 ABW URB 2000 42444 1.18
#> 2 ABW URB 2001 43048 1.41
#> 3 ABW URB 2002 43670 1.43
#> 4 ABW URB 2003 44246 1.31
#> 5 ABW URB 2004 44669 0.951
#> 6 ABW URB 2005 44889 0.491
#> 7 ABW URB 2006 44881 -0.0178
#> 8 ABW URB 2007 44686 -0.435
#> 9 ABW URB 2008 44375 -0.698
#> 10 ABW URB 2009 44052 -0.731
#> # ⊠with 9,494 more rowsLista e kontakteve
Shembulli i fundit, imagjinoni që keni një listë kontaktesh që e keni kopjuar dhe ngjitur nga një web faqe:
contacts <- tribble(
~field, ~value,
"name", "Jiena McLellan",
"company", "Toyota",
"name", "John Smith",
"company", "google",
"email", "john@google.com",
"name", "Huxley Ratcliffe"
)Të sjellësh këtë listë në formë tabulare është mjaft e vështirë, sepse nuk ka një variable që identifikon se cilat të dhëna i përkasin cilit kontakt. Mund ta korrigjojmë këtë duke vënë re se të dhënat për çdo kontakt të ri fillojnë me emrin ("name"), prandaj mund të krijojmë një identifikues unik, duke e rritur me një çdo herë që vlera "name" shfaqet në kolonën field:
contacts %
mutate(
person_id = cumsum(field == "name")
)
contacts#> # A tibble: 6 x 3
#> field value person_id
#> <chr> <chr> <int>
#> 1 name Jiena McLellan 1
#> 2 company Toyota 1
#> 3 name John Smith 2
#> 4 company google 2
#> 5 email john@google.com 2
#> 6 name Huxley Ratcliffe 3Tani, kur kemi një identifikues unik për çdo kontakt, mund të kthejmë fushën dhe vlerën në kolona:
contacts %>%
pivot_wider(names_from = field, values_from = value)#> # A tibble: 3 x 4
#> person_id name company email
#> <int> <chr> <chr> <chr>
#> 1 1 Jiena McLellan Toyota <NA>
#> 2 2 John Smith google john@google.com
#> 3 3 Huxley Ratcliffe <NA> <NA>Përfundimi
Mendimi im personal është se koncepti i ri tidyr është vërtet intuitivisht më i qartë, dhe ndjeshëm superior në funksionalitet ndaj funksioneve të të kaluara spread() dhe gather(). Shpresoj që ky artikull ju ka ndihmuar të kuptoni pivot_longer() dhe pivot_wider().
Burimi: habr.com
