{"id":76291,"date":"2020-04-01T13:42:28","date_gmt":"2020-04-01T11:42:28","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/r-paket-tidyr-i-ego-novye-funkczii-pivot_longer-i-pivot_wider"},"modified":"2020-04-01T13:42:28","modified_gmt":"2020-04-01T11:42:28","slug":"r-paket-tidyr-i-ego-novye-funkczii-pivot_longer-i-pivot_wider","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/r-paket-tidyr-i-ego-novye-funkczii-pivot_longer-i-pivot_wider","title":{"rendered":"Pakiet R tidyr i jego nowe funkcje pivot_longer oraz pivot_wider","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Pakiet <strong>tidyr<\/strong> jest cz\u0119\u015bci\u0105 jednego z najpopularniejszych pakiet\u00f3w w j\u0119zyku R \u2014 <strong>tidyverse<\/strong>.<br \/>\nG\u0142\u00f3wnym celem pakietu jest uporz\u0105dkowanie danych.<\/p>\n<p><\/p>\n<p>Na Habrze jest ju\u017c <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/248741\/\">publikacja<\/a><\/noindex> po\u015bwi\u0119cona temu pakietowi, ale datuje si\u0119 na 2015 rok. A ja chc\u0119 opowiedzie\u0107 o najwa\u017cniejszych zmianach, o kt\u00f3rych kilka dni temu poinformowa\u0142 jego autor Hadley Wickham.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Pakiet R tidyr i jego nowe funkcje pivot_longer oraz pivot_wider\" src=\"\/wp-content\/uploads\/2020\/04\/a290263b63aaea3db70e83a1ec411415.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<blockquote><p><b>SJK<\/b>: Czy funkcje gather() i spread() b\u0119d\u0105 uznawane za przestarza\u0142e?<\/p>\n<p><b>Hadley Wickham<\/b>: W pewnym sensie. Przestaniemy zaleca\u0107 u\u017cycie tych funkcji i poprawia\u0107 b\u0142\u0119dy w nich, ale nadal b\u0119d\u0105 obecne w pakiecie w aktualnym stanie.<\/p><\/blockquote>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"soderzhanie\">Spis tre\u015bci<\/h2>\n<p><\/p>\n<p><em>Je\u015bli interesujesz si\u0119 analiz\u0105 danych, to mog\u0105 Ci\u0119 zainteresowa\u0107 moje <noindex><a rel=\"nofollow\" href=\"https:\/\/t.me\/R4marketing\">telegram<\/a><\/noindex> i <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/R4marketing\/?sub_confirmation=1\">youtube<\/a><\/noindex> kana\u0142y. Wi\u0119kszo\u015b\u0107 ich tre\u015bci po\u015bwi\u0119cona jest j\u0119zykowi R.<\/em><\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#koncepciya-tidydata\">Koncepcja TidyData<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#osnovnye-funkcii-vhodyaschie-v-paket-tydir\">Podstawowe funkcje wchodz\u0105ce w sk\u0142ad pakietu tidyr<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#novaya-koncepciya-preobrazovaniya-dannyh-iz-shirokogo-formata-v-dlinnyy-i-naoborot\">Nowa koncepcja przekszta\u0142cania danych z formatu szerokiego do d\u0142ugiego i odwrotnie<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/ustnovka-naibolee-aktualnoy-versii-tidyr-0839000\">Instalacja najnowszej wersji tidyr 0.8.3.9000<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#perehod-na-novye-funkcii\">Przej\u015bcie na nowe funkcje<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#prostoy-primer-preobrazovaniya-dannyh-iz-shirokogo-formata-v-dlinnyy\">Prosty przyk\u0142ad przekszta\u0142cania danych z formatu szerokiego do d\u0142ugiego<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#specifikacii\">Specyfikacje<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#specifikaciya-s-ispolzovaniem-neskolkih-znacheniyvalue\">Specyfikacja z wykorzystaniem wielu warto\u015bci (.value)<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#preobrazovanie-data-freymov-iz-dlinnogo-formata-k-shirokomu\">Przekszta\u0142canie ramki danych z formatu d\u0142ugiego na szeroki<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#prosteyshiy-primer-privedeniya-tablicy-k-shirokomu-formatu\">Najprostszy przyk\u0142ad przekszta\u0142cania tabeli do formatu szerokiego<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#generaciya-imeni-stolbca-iz-neskolkih-ishodnyh-peremennyh\">Generowanie nazwy kolumny z kilku zmiennych \u017ar\u00f3d\u0142owych<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#neskolko-prodvinutyh-primerov-raboty-s-novoy-koncepciey-tidyr\">Kilka zaawansowanych przyk\u0142ad\u00f3w pracy z now\u0105 koncepcj\u0105 tidyr<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#privedenie-dannyh-k-akkuratnomu-vidu-na-primere-nabora-dannyh-o-perepisi-dohoda-i-arendnoy-platy-v-ssha\">Uporz\u0105dkowanie danych na przyk\u0142adzie zestawu danych dotycz\u0105cego dochod\u00f3w i czynsz\u00f3w w USA<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#vsemirnyy-bank\">Bank \u015awiatowy<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#spisok-kontaktov\">Lista kontakt\u00f3w<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#zaklyuchenie\">Podsumowanie<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"koncepciya-tidydata\">Koncepcja TidyData<\/h2>\n<p><\/p>\n<p>Cel <strong>tidyr<\/strong> \u2014 pom\u00f3c ci uporz\u0105dkowa\u0107 dane w tzw. spos\u00f3b tidy. Uporz\u0105dkowane dane to dane, w kt\u00f3rych: <\/p>\n<p><\/p>\n<ul>\n<li>Ka\u017cda zmienna znajduje si\u0119 w kolumnie. <\/li>\n<li>Ka\u017cde obserwacja to wiersz. <\/li>\n<li>Ka\u017cda warto\u015b\u0107 to kom\u00f3rka.<\/li>\n<\/ul>\n<p><\/p>\n<p>Z danymi uporz\u0105dkowanymi znacznie \u0142atwiej i wygodniej pracowa\u0107 podczas analizy.<\/p>\n<p><\/p>\n<h2 id=\"osnovnye-funkcii-vhodyaschie-v-paket-tidyr\">Podstawowe funkcje wchodz\u0105ce w sk\u0142ad pakietu tidyr<\/h2>\n<p><\/p>\n<p>tidyr zawiera zestaw funkcji przeznaczonych do przekszta\u0142cania tabel:<\/p>\n<p><\/p>\n<ul>\n<li><code>fill()<\/code> \u2014 wype\u0142nianie brakuj\u0105cych warto\u015bci w kolumnie poprzednimi warto\u015bciami;<\/li>\n<li><code>separate()<\/code> \u2014 dzieli jedno pole na kilka przez separator;<\/li>\n<li><code>unite()<\/code> \u2014 wykonuje operacj\u0119 \u0142\u0105czenia kilku p\u00f3l w jedno, dzia\u0142anie odwrotne do funkcji <code>separate()<\/code>;<\/li>\n<li><code>pivot_longer()<\/code> \u2014 funkcja przekszta\u0142caj\u0105ca dane z formatu szerokiego do d\u0142ugiego;<\/li>\n<li><code>pivot_wider()<\/code> \u2014 funkcja przekszta\u0142caj\u0105ca dane z formatu d\u0142ugiego do szerokiego. Operacja odwrotna do tej, kt\u00f3r\u0105 wykonuje funkcja <code>pivot_longer()<\/code>.<\/li>\n<li><code>gather()<\/code><strong>przestarza\u0142a<\/strong> \u2014 funkcja przekszta\u0142caj\u0105ca dane z formatu szerokiego do d\u0142ugiego;<\/li>\n<li><code>spread()<\/code><strong>przestarza\u0142a<\/strong> \u2014 funkcja przekszta\u0142caj\u0105ca dane z formatu d\u0142ugiego do szerokiego. Operacja odwrotna do tej, kt\u00f3r\u0105 wykonuje funkcja <code>gather()<\/code>.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"novaya-koncepciya-preobrazovaniya-dannyh-iz-shirokogo-formata-v-dlinnyy-i-naoborot\">Nowa koncepcja przekszta\u0142cania danych z formatu szerokiego do d\u0142ugiego i odwrotnie<\/h2>\n<p><\/p>\n<p>Wcze\u015bniej do podobnego rodzaju przekszta\u0142ce\u0144 u\u017cywano funkcji <code>gather()<\/code> i <code>spread()<\/code>. Z lat u\u017cywania tych funkcji sta\u0142o si\u0119 oczywiste, \u017ce dla wi\u0119kszo\u015bci u\u017cytkownik\u00f3w, w tym autora pakietu, nazwy tych funkcji oraz ich argumenty by\u0142y do\u015b\u0107 niejasne, co powodowa\u0142o trudno\u015bci w ich wyszukiwaniu i zrozumieniu, kt\u00f3ra z tych funkcji przekszta\u0142ca ramk\u0119 danych z formatu szerokiego na d\u0142ugi, i odwrotnie.<\/p>\n<p><\/p>\n<p>W zwi\u0105zku z tym w <strong>tidyr<\/strong> dodano dwie nowe, istotne funkcje, kt\u00f3re maj\u0105 na celu transformacj\u0119 ramek danych.<\/p>\n<p><\/p>\n<p>Nowe funkcje <code>pivot_longer()<\/code> i <code>pivot_wider()<\/code> zosta\u0142y stworzone pod wp\u0142ywem kilku funkcji z pakietu <strong>cdata<\/strong>, stworzonego przez Johna Mounta i Nin\u0119 Zume\u0142.<\/p>\n<p><\/p>\n<h3 id=\"ustanovka-naibolee-aktualnoy-versii-tidyr-0839000\">Instalacja najnowszej wersji tidyr 0.8.3.9000<\/h3>\n<p><\/p>\n<p>Aby zainstalowa\u0107 najnowsz\u0105 wersj\u0119 pakietu <strong>tidyr<\/strong> <em>0.8.3.9000<\/em>, w kt\u00f3rej dost\u0119pne s\u0105 nowe funkcje, skorzystaj z nast\u0119puj\u0105cego kodu.<\/p>\n<p><\/p>\n<p><code>devtools::install_github(\"tidyverse\/tidyr\")<\/code><\/p>\n<p><\/p>\n<p>W momencie pisania tego artyku\u0142u te funkcje s\u0105 dost\u0119pne tylko w wersji dev pakietu na GitHubie.<\/p>\n<p><\/p>\n<h3 id=\"perehod-na-novye-funkcii\">Przej\u015bcie na nowe funkcje<\/h3>\n<p><\/p>\n<p>Zreszt\u0105, przet\u0142umaczenie starych skrypt\u00f3w na nowe funkcje nie jest trudne; aby lepiej to zrozumie\u0107, wezm\u0119 przyk\u0142ad z dokumentacji starych funkcji i poka\u017c\u0119, jak te same operacje wykonuje si\u0119 przy u\u017cyciu nowych <code>pivot_*()<\/code> funkcje.<\/p>\n<p><\/p>\n<p>Przekszta\u0142canie formatu szerokiego na d\u0142ugi.<\/p>\n<p>\n<b class=\"spoiler_title\">Przyk\u0142ad kodu z dokumentacji funkcji gather<\/b><\/p>\n<pre><code class=\"plaintext\"># example\nlibrary(dplyr)\nstocks &lt;- data.frame(\n  time = as.Date('2009-01-01') + 0:9,\n  X = rnorm(10, 0, 1),\n  Y = rnorm(10, 0, 2),\n  Z = rnorm(10, 0, 4)\n)\n\n# old\nstocks_gather &lt;- stocks %&gt;% gather(key   = stock, \n                                   value = price, \n                                   -time)\n\n# new\nstocks_long   &lt;- stocks %&gt;% pivot_longer(cols      = -time, \n                                       names_to  = &quot;stock&quot;, \n                                       values_to = &quot;price&quot;)\n<\/code><\/pre>\n<p><\/p>\n<p>Przekszta\u0142canie formatu d\u0142ugiego na szeroki.<\/p>\n<p>\n<b class=\"spoiler_title\">Przyk\u0142ad kodu z dokumentacji funkcji spread<\/b><\/p>\n<pre><code class=\"plaintext\"># old\nstocks_spread &lt;- stocks_gather %&gt;% spread(key = stock, \n                                          value = price) \n\n# new \nstock_wide    &lt;- stocks_long %&gt;% pivot_wider(names_from  = &quot;stock&quot;,\n                                            values_from = &quot;price&quot;)\n<\/code><\/pre>\n<p><\/p>\n<p>Poniewa\u017c w powy\u017cszych przyk\u0142adach pracy z <code>pivot_longer()<\/code> i <code>pivot_wider()<\/code>, w oryginalnej tabeli <em>stocks<\/em> brakuje kolumn wymienionych w argumentach <em>names_to<\/em> i <em>values_to<\/em> ich nazwy nale\u017cy podawa\u0107 w cudzys\u0142owie.<\/p>\n<p><\/p>\n<p>Tabela, z pomoc\u0105 kt\u00f3rej naj\u0142atwiej b\u0119dzie Ci zrozumie\u0107, jak przej\u015b\u0107 na now\u0105 koncepcj\u0119 <strong>tidyr<\/strong>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Pakiet R tidyr i jego nowe funkcje pivot_longer oraz pivot_wider\" src=\"\/wp-content\/uploads\/2020\/04\/fe598b5cd152088a2f1b23b846d212e9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"primechanie-ot-avtora\">Notatka od autora<\/h2>\n<p><\/p>\n<blockquote><p>Ca\u0142y poni\u017cszy tekst jest adaptacyjny, a wr\u0119cz powiedzia\u0142bym, \u017ce swobodnym t\u0142umaczeniem <noindex><a rel=\"nofollow\" href=\"https:\/\/tidyr.tidyverse.org\/dev\/articles\/pivot.html\">winylet<\/a><\/noindex> z oficjalnej strony biblioteki tidyverse.<\/p><\/blockquote>\n<p><\/p>\n<h2 id=\"prostoy-primer-preobrazovaniya-dannyh-iz-shirokogo-formata-v-dlinnyy\">Prosty przyk\u0142ad przekszta\u0142cania danych z formatu szerokiego do d\u0142ugiego<\/h2>\n<p><\/p>\n<p><code>pivot_longer ()<\/code> \u2014 przekszta\u0142ca zbiory danych w d\u0142u\u017csze, zmniejszaj\u0105c liczb\u0119 kolumn i zwi\u0119kszaj\u0105c liczb\u0119 wierszy.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Pakiet R tidyr i jego nowe funkcje pivot_longer oraz pivot_wider\" src=\"\/wp-content\/uploads\/2020\/04\/fc88b99f2fecdcdaa6179d2e7d29e59d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aby wykona\u0107 przyk\u0142ady przedstawione w artykule, najpierw nale\u017cy za\u0142adowa\u0107 potrzebne pakiety:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">library(tidyr)\nlibrary(dplyr)\nlibrary(readr)<\/code><\/pre>\n<p><\/p>\n<p>Za\u0142\u00f3\u017cmy, \u017ce mamy tabel\u0119 z wynikami ankiety, w kt\u00f3rej (mi\u0119dzy innymi) pytano ludzi o ich religi\u0119 i roczne dochody:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 18 x 11\n#&gt;    religion `&lt;$10k` `$10-20k` `$20-30k` `$30-40k` `$40-50k` `$50-75k`\n#&gt;    &lt;chr&gt;      &lt;dbl&gt;     &lt;dbl&gt;     &lt;dbl&gt;     &lt;dbl&gt;     &lt;dbl&gt;     &lt;dbl&gt;\n#&gt;  1 Agnostic      27        34        60        81        76       137\n#&gt;  2 Atheist       12        27        37        52        35        70\n#&gt;  3 Buddhist      27        21        30        34        33        58\n#&gt;  4 Catholic     418       617       732       670       638      1116\n#&gt;  5 Don\u2019t k\u2026      15        14        15        11        10        35\n#&gt;  6 Evangel\u2026     575       869      1064       982       881      1486\n#&gt;  7 Hindu          1         9         7         9        11        34\n#&gt;  8 Histori\u2026     228       244       236       238       197       223\n#&gt;  9 Jehovah\u2026      20        27        24        24        21        30\n#&gt; 10 Jewish        19        19        25        25        30        95\n#&gt; # \u2026 with 8 more rows, and 4 more variables: `$75-100k` &lt;dbl&gt;,\n#&gt; #   `$100-150k` &lt;dbl&gt;, `&gt;150k` &lt;dbl&gt;, `Don't know\/refused` &lt;dbl&gt;<\/code><\/pre>\n<p><\/p>\n<p>Ta tabela zawiera dane o religii respondent\u00f3w w wierszach, a poziom dochodu jest rozmieszczony w nazwach kolumn. Liczba respondent\u00f3w w ka\u017cdej kategorii jest przechowywana w warto\u015bciach kom\u00f3rek na przeci\u0119ciu religii i poziomu dochodu. Aby doprowadzi\u0107 tabel\u0119 do schludnego, poprawnego formatu, wystarczy u\u017cy\u0107 <code>pivot_longer()<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">pew %&gt;% \n  pivot_longer(cols = -religion, names_to = \"income\", values_to = \"count\")<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">pew %&gt;% \n  pivot_longer(cols = -religion, names_to = \"income\", values_to = \"count\")\n#&gt; # A tibble: 180 x 3\n#&gt;    religion income             count\n#&gt;                      \n#&gt;  1 Agnostyk   2 Agnostyk 10-20k              34\n#&gt;  3 Agnostyk 20-30k              60\n#&gt;  4 Agnostyk 30-40k              81\n#&gt;  5 Agnostyk 40-50k              76\n#&gt;  6 Agnostyk 50-75k             137\n#&gt;  7 Agnostyk 75-100k            122\n#&gt;  8 Agnostyk 100-150k           109\n#&gt;  9 Agnostyk &gt;150k               84\n#&gt; 10 Agnostyk Nie wiem\/odm\u00f3wi\u0142    96\n#&gt; # \u2026 z 170 wi\u0119cej wierszy<\/code><\/pre>\n<p><\/p>\n<p>Argumenty funkcji <code>pivot_longer()<\/code><\/p>\n<p><\/p>\n<ul>\n<li>Pierwszy argument <em>cols<\/em>, opisuje, kt\u00f3re kolumny nale\u017cy po\u0142\u0105czy\u0107. W tym przypadku wszystkie kolumny, z wyj\u0105tkiem <em>time<\/em>.<\/li>\n<li>Argument <em>names_to<\/em> nadaje nazw\u0119 zmiennej, kt\u00f3ra zostanie utworzona z nazw kolumn, kt\u00f3re po\u0142\u0105czyli\u015bmy.<\/li>\n<li><em>values_to<\/em> nadaje nazw\u0119 zmiennej, kt\u00f3ra zostanie utworzona z danych przechowywanych w warto\u015bciach kom\u00f3rek po\u0142\u0105czonych kolumn.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"specifikacii\">Specyfikacje<\/h2>\n<p><\/p>\n<p>To nowa funkcjonalno\u015b\u0107 pakietu <strong>tidyr<\/strong>, kt\u00f3ra wcze\u015bniej podczas pracy z przestarza\u0142ymi funkcjami by\u0142a niedost\u0119pna.<\/p>\n<p><\/p>\n<p>Specyfikacja to ramka danych, gdzie ka\u017cdy wiersz odpowiada jednej kolumnie w nowej wyj\u015bciowej ramce danych oraz dw\u00f3m specjalnym kolumnom, kt\u00f3re zaczynaj\u0105 si\u0119 od: <\/p>\n<p><\/p>\n<ul>\n<li><em>.name<\/em> zawiera oryginaln\u0105 nazw\u0119 kolumny. <\/li>\n<li><em>.value<\/em> zawiera nazw\u0119 kolumny, do kt\u00f3rej b\u0119d\u0105 wchodzi\u0142y warto\u015bci kom\u00f3rek. <\/li>\n<\/ul>\n<p><\/p>\n<p>Pozosta\u0142e kolumny specyfikacji odzwierciedlaj\u0105, jak w nowej kolumnie b\u0119dzie wy\u015bwietlana nazwa skompresowanych kolumn z <em>.name<\/em>.<\/p>\n<p><\/p>\n<p>Specyfikacja opisuje metadane przechowywane w nazwie kolumny, z jednym wierszem dla ka\u017cdej kolumny i jedn\u0105 kolumn\u0105 dla ka\u017cdej zmiennej po\u0142\u0105czonej z nazw\u0105 kolumny; by\u0107 mo\u017ce obecnie taka definicja wydaje si\u0119 skomplikowana, ale po przeanalizowaniu kilku przyk\u0142ad\u00f3w wszystko stanie si\u0119 znacznie ja\u015bniejsze.<\/p>\n<p><\/p>\n<p>Istota specyfikacji polega na tym, \u017ce mo\u017cna wyci\u0105ga\u0107, modyfikowa\u0107 i przypisywa\u0107 nowe metadane do przekszta\u0142canego ramka danych.<\/p>\n<p><\/p>\n<p>Do pracy ze specyfikacjami przy przekszta\u0142caniu tabeli z formatu szerokiego na d\u0142ugi s\u0142u\u017cy funkcja <code>pivot_longer_spec()<\/code>.<\/p>\n<p><\/p>\n<p>Ta funkcja dzia\u0142a w ten spos\u00f3b, \u017ce bierze dowoln\u0105 ramk\u0119 danych i formuje jej metadane w opisany powy\u017cej spos\u00f3b. <\/p>\n<p><\/p>\n<p>Na przyk\u0142ad, we\u017amy zestaw danych who, kt\u00f3ry jest dostarczany razem z pakietem. <strong>tidyr<\/strong>Ten zestaw danych zawiera informacje dostarczane przez \u015awiatow\u0105 Organizacj\u0119 Zdrowia na temat zachorowalno\u015bci na gru\u017alic\u0119.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">who\n#&gt; # A tibble: 7,240 x 60\n#&gt;    country iso2  iso3   year new_sp_m014 new_sp_m1524 new_sp_m2534\n#&gt;        &lt;chr&gt; &lt;int&gt;       &lt;int&gt;        &lt;int&gt;        &lt;int&gt;\n#&gt;  1 Afghan\u2026 AF    AFG    1980          NA           NA           NA\n#&gt;  2 Afghan\u2026 AF    AFG    1981          NA           NA           NA\n#&gt;  3 Afghan\u2026 AF    AFG    1982          NA           NA           NA\n#&gt;  4 Afghan\u2026 AF    AFG    1983          NA           NA           NA\n#&gt;  5 Afghan\u2026 AF    AFG    1984          NA           NA           NA\n#&gt;  6 Afghan\u2026 AF    AFG    1985          NA           NA           NA\n#&gt;  7 Afghan\u2026 AF    AFG    1986          NA           NA           NA\n#&gt;  8 Afghan\u2026 AF    AFG    1987          NA           NA           NA\n#&gt;  9 Afghan\u2026 AF    AFG    1988          NA           NA           NA\n#&gt; 10 Afghan\u2026 AF    AFG    1989          NA           NA           NA\n#&gt; # \u2026 z 7,230 wi\u0119cej wierszy i 53 wi\u0119cej zmiennych<\/code><\/pre>\n<p><\/p>\n<p>Zbudujemy jego specyfikacj\u0119.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">spec %\n  pivot_longer_spec(new_sp_m014:newrel_f65, values_to = \"count\")<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 56 x 3\n#&gt;    .name        .value name        \n#&gt;    &lt;chr&gt;        &lt;chr&gt;  &lt;chr&gt;       \n#&gt;  1 new_sp_m014  count  new_sp_m014 \n#&gt;  2 new_sp_m1524 count  new_sp_m1524\n#&gt;  3 new_sp_m2534 count  new_sp_m2534\n#&gt;  4 new_sp_m3544 count  new_sp_m3544\n#&gt;  5 new_sp_m4554 count  new_sp_m4554\n#&gt;  6 new_sp_m5564 count  new_sp_m5564\n#&gt;  7 new_sp_m65   count  new_sp_m65  \n#&gt;  8 new_sp_f014  count  new_sp_f014 \n#&gt;  9 new_sp_f1524 count  new_sp_f1524\n#&gt; 10 new_sp_f2534 count  new_sp_f2534\n#&gt; # \u2026 with 46 more rows<\/code><\/pre>\n<p><\/p>\n<p>Pola <em>kraj<\/em>, <em>iso2<\/em>, <em>iso3<\/em> s\u0105 ju\u017c zmiennymi. Naszym zadaniem jest odwr\u00f3cenie kolumn z <em>new_sp_m014<\/em> w <em>newrel_f65<\/em>.<\/p>\n<p><\/p>\n<p>W nazwach tych kolumn przechowywane s\u0105 nast\u0119puj\u0105ce informacje:<\/p>\n<p><\/p>\n<ul>\n<li>Prefiks <code>new_<\/code> oznacza, \u017ce kolumna zawiera dane o nowych przypadkach zachorowa\u0144 na gru\u017alic\u0119, a bie\u017c\u0105cy ramka danych zawiera informacje tylko o nowych zachorowaniach, dlatego ten prefiks w kontek\u015bcie nie niesie \u017cadnego znaczenia.<\/li>\n<li><code>sp<\/code>\/<code>rel<\/code>\/<code>sp<\/code>\/<code>ep<\/code> opisuje spos\u00f3b diagnozowania choroby.<\/li>\n<li><code>m<\/code>\/<code>f<\/code> p\u0142ci pacjenta.<\/li>\n<li><code>014<\/code>\/<code>1524<\/code>\/<code>2535<\/code>\/<code>3544<\/code>\/<code>4554<\/code>\/<code>65<\/code> zakres wiekowy pacjenta.<\/li>\n<\/ul>\n<p><\/p>\n<p>Mo\u017cemy rozdzieli\u0107 te kolumny przy u\u017cyciu funkcji <code>extract()<\/code>, wykorzystuj\u0105c wyra\u017cenie regularne.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">spec %\n        extract(name, c(\"diagnosis\", \"gender\", \"age\"), \"new_?(.*)_(.)(.*)\")<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 56 x 5\n#&gt;    .name        .value diagnosis gender age  \n#&gt;    &lt;chr&gt;        &lt;chr&gt;  &lt;chr&gt;     &lt;chr&gt;  &lt;chr&gt;\n#&gt;  1 new_sp_m014  count  sp        m      014  \n#&gt;  2 new_sp_m1524 count  sp        m      1524 \n#&gt;  3 new_sp_m2534 count  sp        m      2534 \n#&gt;  4 new_sp_m3544 count  sp        m      3544 \n#&gt;  5 new_sp_m4554 count  sp        m      4554 \n#&gt;  6 new_sp_m5564 count  sp        m      5564 \n#&gt;  7 new_sp_m65   count  sp        m      65   \n#&gt;  8 new_sp_f014  count  sp        f      014  \n#&gt;  9 new_sp_f1524 count  sp        f      1524 \n#&gt; 10 new_sp_f2534 count  sp        f      2534 \n#&gt; # \u2026 with 46 more rows<\/code><\/pre>\n<p><\/p>\n<p>Zauwa\u017c, \u017ce kolumna <em>.name<\/em> powinna pozosta\u0107 niezmieniona, poniewa\u017c to jest nasz indeks w nazwach kolumn pierwotnego zestawu danych. <\/p>\n<p><\/p>\n<p>P\u0142e\u0107 i wiek (kolumny <em>gender<\/em> i <em>age<\/em>) maj\u0105 ustalone i znane warto\u015bci, dlatego zaleca si\u0119 przekszta\u0142cenie tych kolumn w czynniki:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">spec %\n            mutate(\n              gender = factor(gender, levels = c(\"f\", \"m\")),\n              age = factor(age, levels = unique(age), ordered = TRUE)\n            ) <\/code><\/pre>\n<p><\/p>\n<p>Na koniec, aby zastosowa\u0107 stworzon\u0105 przez nas specyfikacj\u0119 do pierwotnej ramki danych <em>who<\/em> musimy u\u017cy\u0107 argumentu <em>spec<\/em> w funkcji <code>pivot_longer()<\/code>.<\/p>\n<p><\/p>\n<p><code>who %&gt;% pivot_longer(spec = spec)<\/code><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 405,440 x 8\n#&gt;    country     iso2  iso3   year diagnosis gender age   count\n#&gt;    &lt;chr&gt;       &lt;chr&gt; &lt;chr&gt; &lt;int&gt; &lt;chr&gt;     &lt;fct&gt;  &lt;ord&gt; &lt;int&gt;\n#&gt;  1 Afghanistan AF    AFG    1980 sp        m      014      NA\n#&gt;  2 Afghanistan AF    AFG    1980 sp        m      1524     NA\n#&gt;  3 Afghanistan AF    AFG    1980 sp        m      2534     NA\n#&gt;  4 Afghanistan AF    AFG    1980 sp        m      3544     NA\n#&gt;  5 Afghanistan AF    AFG    1980 sp        m      4554     NA\n#&gt;  6 Afghanistan AF    AFG    1980 sp        m      5564     NA\n#&gt;  7 Afghanistan AF    AFG    1980 sp        m      65       NA\n#&gt;  8 Afghanistan AF    AFG    1980 sp        f      014      NA\n#&gt;  9 Afghanistan AF    AFG    1980 sp        f      1524     NA\n#&gt; 10 Afghanistan AF    AFG    1980 sp        f      2534     NA\n#&gt; # \u2026 with 405,430 more rows<\/code><\/pre>\n<p><\/p>\n<p>Wszystko, co w\u0142a\u015bnie zrobili\u015bmy, mo\u017ce by\u0107 schematycznie przedstawione w nast\u0119puj\u0105cy spos\u00f3b:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Pakiet R tidyr i jego nowe funkcje pivot_longer oraz pivot_wider\" src=\"\/wp-content\/uploads\/2020\/04\/77c8c266c205e1b087738d31de8b8523.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"specifikaciya-s-ispolzovaniem-neskolkih-znacheniyvalue\">Specyfikacja z wykorzystaniem wielu warto\u015bci (.value)<\/h2>\n<p><\/p>\n<p>W podanym powy\u017cej przyk\u0142adzie kolumna specyfikacji <em>.value<\/em> zawiera\u0142a tylko jedn\u0105 warto\u015b\u0107, co w wi\u0119kszo\u015bci przypadk\u00f3w ma miejsce. <\/p>\n<p><\/p>\n<p>Jednak czasami mo\u017ce zaistnie\u0107 sytuacja, w kt\u00f3rej trzeba b\u0119dzie zebra\u0107 warto\u015bci z kolumn o r\u00f3\u017cnych typach danych. Dzi\u0119ki przestarza\u0142ej funkcji <code>spread()<\/code> by\u0142oby to do\u015b\u0107 trudne.<\/p>\n<p><\/p>\n<p>Poni\u017cszy przyk\u0142ad zosta\u0142 zapo\u017cyczony z <noindex><a rel=\"nofollow\" href=\"https:\/\/cran.r-project.org\/web\/packages\/data.table\/vignettes\/datatable-reshape.html\">winylet<\/a><\/noindex> pakietu <strong>data.table<\/strong>.<\/p>\n<p><\/p>\n<p>Utw\u00f3rzmy przyk\u0142adowy dataframe.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">family &lt;- tibble::tribble(\n  ~family,  ~dob_child1,  ~dob_child2, ~gender_child1, ~gender_child2,\n       1L, &quot;1998-11-26&quot;, &quot;2000-01-29&quot;,             1L,             2L,\n       2L, &quot;1996-06-22&quot;,           NA,             2L,             NA,\n       3L, &quot;2002-07-11&quot;, &quot;2004-04-05&quot;,             2L,             2L,\n       4L, &quot;2004-10-10&quot;, &quot;2009-08-27&quot;,             1L,             1L,\n       5L, &quot;2000-12-05&quot;, &quot;2005-02-28&quot;,             2L,             1L,\n)\nfamily % mutate_at(vars(starts_with(\"dob\")), parse_date)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 5 x 5\n#&gt;   family dob_child1 dob_child2 gender_child1 gender_child2\n#&gt;    &lt;int&gt; &lt;date&gt;     &lt;date&gt;             &lt;int&gt;         &lt;int&gt;\n#&gt; 1      1 1998-11-26 2000-01-29             1             2\n#&gt; 2      2 1996-06-22 NA                     2            NA\n#&gt; 3      3 2002-07-11 2004-04-05             2             2\n#&gt; 4      4 2004-10-10 2009-08-27             1             1\n#&gt; 5      5 2000-12-05 2005-02-28             2             1<\/code><\/pre>\n<p><\/p>\n<p>Utworzony dataframe w ka\u017cdej linii zawiera dane o dzieciach jednej rodziny. W rodzinach mo\u017ce by\u0107 jedno lub dwoje dzieci. Dla ka\u017cdego dziecka podawane s\u0105 dane o dacie urodzenia i p\u0142ci, przy czym dane dla ka\u017cdego dziecka znajduj\u0105 si\u0119 w osobnych kolumnach, a naszym zadaniem jest przekszta\u0142cenie tych danych do odpowiedniego formatu analitycznego.<\/p>\n<p><\/p>\n<p>Zauwa\u017c, \u017ce mamy dwie zmienne z informacjami o ka\u017cdym dziecku: jego p\u0142e\u0107 i data urodzenia (kolumny z prefiksem <em>dob<\/em> zawieraj\u0105 dat\u0119 urodzenia, kolumny z prefiksem <em>gender<\/em> zawieraj\u0105 p\u0142e\u0107 dziecka). W oczekiwanym wyniku musz\u0105 one znajdowa\u0107 si\u0119 w osobnych kolumnach. Mo\u017cemy to osi\u0105gn\u0105\u0107, generuj\u0105c specyfikacj\u0119, w kt\u00f3rej kolumna <code>.value<\/code> b\u0119dzie mia\u0142a dwie r\u00f3\u017cne warto\u015bci.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">spec %\n  pivot_longer_spec(-family) %&gt;%\n  separate(col = name, into = c(\".value\", \"child\"))%&gt;%\n  mutate(child = parse_number(child))\n<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 4 x 3\n#&gt;   .name         .value child\n#&gt;   &lt;chr&gt;         &lt;chr&gt;  &lt;dbl&gt;\n#&gt; 1 dob_child1    dob        1\n#&gt; 2 dob_child2    dob        2\n#&gt; 3 gender_child1 gender     1\n#&gt; 4 gender_child2 gender     2<\/code><\/pre>\n<p><\/p>\n<p>Zatem przeanalizujmy krok po kroku dzia\u0142ania, jakie wykonuje powy\u017cszy kod.<\/p>\n<p><\/p>\n<ul>\n<li><code>pivot_longer_spec(-family)<\/code> \u2014 tworzymy specyfikacj\u0119, kt\u00f3ra \u0142\u0105czy wszystkie dost\u0119pne kolumny, z wyj\u0105tkiem kolumny family.<\/li>\n<li><code>separate(col = name, into = c(\".value\", \"child\"))<\/code> \u2014 dzielimy kolumn\u0119 <em>.name<\/em>, kt\u00f3ra zawiera nazwy oryginalnych p\u00f3l, wed\u0142ug podkre\u015blenia i umieszczamy uzyskane warto\u015bci w kolumnach <em>.value<\/em> i <em>child<\/em>.<\/li>\n<li><code>mutate(child = parse_number(child))<\/code> \u2014 przekszta\u0142camy warto\u015bci pola <em>child<\/em> z tekstowego na numeryczny typ danych.<\/li>\n<\/ul>\n<p><\/p>\n<p>Teraz mo\u017cemy zastosowa\u0107 otrzyman\u0105 specyfikacj\u0119 do oryginalnego dataframe'u i przekszta\u0142ci\u0107 tabel\u0119 do po\u017c\u0105danego formatu.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">family %&gt;% \n    pivot_longer(spec = spec, na.rm = T)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 9 x 4\n#&gt;   family child dob        gender\n#&gt;    &lt;int&gt; &lt;dbl&gt; &lt;date&gt;      &lt;int&gt;\n#&gt; 1      1     1 1998-11-26      1\n#&gt; 2      1     2 2000-01-29      2\n#&gt; 3      2     1 1996-06-22      2\n#&gt; 4      3     1 2002-07-11      2\n#&gt; 5      3     2 2004-04-05      2\n#&gt; 6      4     1 2004-10-10      1\n#&gt; 7      4     2 2009-08-27      1\n#&gt; 8      5     1 2000-12-05      2\n#&gt; 9      5     2 2005-02-28      1<\/code><\/pre>\n<p><\/p>\n<p>U\u017cywamy argumentu <code>na.rm = TRUE<\/code>, poniewa\u017c obecny kszta\u0142t danych zmusza do tworzenia dodatkowych wierszy dla nieistniej\u0105cych obserwacji. Poniewa\u017c rodzina 2 ma tylko jedno dziecko, <code>na.rm = TRUE<\/code> zapewnia, \u017ce rodzina 2 b\u0119dzie mia\u0142a jeden wiersz w danych wyj\u015bciowych.<\/p>\n<p><\/p>\n<h2 id=\"preobrazovanie-data-freymov-iz-dlinnogo-formata-k-shirokomu\">Przekszta\u0142canie ramki danych z formatu d\u0142ugiego na szeroki<\/h2>\n<p><\/p>\n<p><code>pivot_wider()<\/code> \u2014 jest odwrotn\u0105 transformacj\u0105, a zatem zwi\u0119ksza liczb\u0119 kolumn ramki danych kosztem zmniejszenia liczby wierszy.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Pakiet R tidyr i jego nowe funkcje pivot_longer oraz pivot_wider\" src=\"\/wp-content\/uploads\/2020\/04\/b470664e06f362d6f0ea6df9c1ed426d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tego rodzaju transformacja jest rzadko stosowana do porz\u0105dkowania danych, niemniej jednak ta technika mo\u017ce by\u0107 przydatna do tworzenia tabel przestawnych wykorzystywanych w prezentacjach lub do integracji z innymi narz\u0119dziami.<\/p>\n<p><\/p>\n<p>Funkcje <code>pivot_longer()<\/code> i <code>pivot_wider()<\/code> s\u0105 symetryczne i wykonuj\u0105 odwrotne dzia\u0142ania, tzn: <code>df %&gt;% pivot_longer(spec = spec) %&gt;% pivot_wider(spec = spec)<\/code> i <code>df %&gt;% pivot_wider(spec = spec) %&gt;% pivot_longer(spec = spec)<\/code> zwr\u00f3ci oryginalny df.<\/p>\n<p><\/p>\n<h3 id=\"prosteyshiy-primer-privedeniya-tablicy-k-shirokomu-formatu\">Najprostszy przyk\u0142ad przekszta\u0142cania tabeli do formatu szerokiego<\/h3>\n<p><\/p>\n<p>W celu demonstrowania dzia\u0142ania funkcji <code>pivot_wider()<\/code> b\u0119dziemy u\u017cywa\u0107 zestawu danych <em>fish_encounters<\/em>, w kt\u00f3rym przechowywane s\u0105 informacje o tym, jak r\u00f3\u017cne stacje rejestruj\u0105 ruch ryb w rzece.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 114 x 3\n#&gt;    fish  station  seen\n#&gt;    &lt;fct&gt; &lt;fct&gt;   &lt;int&gt;\n#&gt;  1 4842  Release     1\n#&gt;  2 4842  I80_1       1\n#&gt;  3 4842  Lisbon      1\n#&gt;  4 4842  Rstr        1\n#&gt;  5 4842  Base_TD     1\n#&gt;  6 4842  BCE         1\n#&gt;  7 4842  BCW         1\n#&gt;  8 4842  BCE2        1\n#&gt;  9 4842  BCW2        1\n#&gt; 10 4842  MAE         1\n#&gt; # \u2026 with 104 more rows<\/code><\/pre>\n<p><\/p>\n<p>W wi\u0119kszo\u015bci przypadk\u00f3w, tabela ta b\u0119dzie bardziej infromatywna i wygodna w u\u017cyciu, gdy informacje o ka\u017cdej stacji zostan\u0105 przedstawione w osobnej kolumnie.<\/p>\n<p><\/p>\n<p><code>fish_encounters %&gt;% pivot_wider(names_from = station, values_from = seen)<\/code><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">fish_encounters %&gt;% pivot_wider(names_from = station, values_from = seen)\n#&gt; # A tibble: 19 x 12\n#&gt;    fish  Release I80_1 Lisbon  Rstr Base_TD   BCE   BCW  BCE2  BCW2   MAE\n#&gt;        &lt;int&gt;  &lt;int&gt; &lt;int&gt;   &lt;int&gt; &lt;int&gt; &lt;int&gt; &lt;int&gt; &lt;int&gt; &lt;int&gt;\n#&gt;  1 4842        1     1      1     1       1     1     1     1     1     1\n#&gt;  2 4843        1     1      1     1       1     1     1     1     1     1\n#&gt;  3 4844        1     1      1     1       1     1     1     1     1     1\n#&gt;  4 4845        1     1      1     1       1    NA    NA    NA    NA    NA\n#&gt;  5 4847        1     1      1    NA      NA    NA    NA    NA    NA    NA\n#&gt;  6 4848        1     1      1     1      NA    NA    NA    NA    NA    NA\n#&gt;  7 4849        1     1     NA    NA      NA    NA    NA    NA    NA    NA\n#&gt;  8 4850        1     1     NA     1       1     1     1    NA    NA    NA\n#&gt;  9 4851        1     1     NA    NA      NA    NA    NA    NA    NA    NA\n#&gt; 10 4854        1     1     NA    NA      NA    NA    NA    NA    NA    NA\n#&gt; # \u2026 z 9 innymi wierszami i 1 inn\u0105 zmienn\u0105: MAW<\/code><\/pre>\n<p><\/p>\n<p>Ten zestaw danych rejestruje informacje tylko w przypadkach, gdy ryba zosta\u0142a wykryta przez stacj\u0119, tzn. je\u015bli jaka\u015b ryba nie zosta\u0142a zarejestrowana przez jak\u0105\u015b stacj\u0119, tych danych w tabeli nie b\u0119dzie. Oznacza to, \u017ce dane wyj\u015bciowe b\u0119d\u0105 wype\u0142nione NA. <\/p>\n<p><\/p>\n<p>Jednak w tym przypadku wiemy, \u017ce brak wpisu oznacza, \u017ce ryba nie zosta\u0142a zauwa\u017cona, dlatego mo\u017cemy u\u017cy\u0107 argumentu <em>values_fill<\/em> w funkcji <code>pivot_wider()<\/code> aby uzupe\u0142ni\u0107 te brakuj\u0105ce warto\u015bci zerami:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">fish_encounters %&gt;% pivot_wider(\n  names_from = station, \n  values_from = seen,\n  values_fill = list(seen = 0)\n)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 19 x 12\n#&gt;    fish  Release I80_1 Lisbon  Rstr Base_TD   BCE   BCW  BCE2  BCW2   MAE\n#&gt;    &lt;fct&gt;   &lt;int&gt; &lt;int&gt;  &lt;int&gt; &lt;int&gt;   &lt;int&gt; &lt;int&gt; &lt;int&gt; &lt;int&gt; &lt;int&gt; &lt;int&gt;\n#&gt;  1 4842        1     1      1     1       1     1     1     1     1     1\n#&gt;  2 4843        1     1      1     1       1     1     1     1     1     1\n#&gt;  3 4844        1     1      1     1       1     1     1     1     1     1\n#&gt;  4 4845        1     1      1     1       1     0     0     0     0     0\n#&gt;  5 4847        1     1      1     0       0     0     0     0     0     0\n#&gt;  6 4848        1     1      1     1       0     0     0     0     0     0\n#&gt;  7 4849        1     1      0     0       0     0     0     0     0     0\n#&gt;  8 4850        1     1      0     1       1     1     1     0     0     0\n#&gt;  9 4851        1     1      0     0       0     0     0     0     0     0\n#&gt; 10 4854        1     1      0     0       0     0     0     0     0     0\n#&gt; # \u2026 with 9 more rows, and 1 more variable: MAW &lt;int&gt;<\/code><\/pre>\n<p><\/p>\n<h3 id=\"generaciya-imeni-stolbca-iz-neskolkih-ishodnyh-peremennyh\">Generowanie nazwy kolumny z kilku zmiennych \u017ar\u00f3d\u0142owych<\/h3>\n<p><\/p>\n<p>Wyobra\u017a sobie, \u017ce mamy tabel\u0119 zawieraj\u0105c\u0105 kombinacj\u0119 produktu, kraju i roku. Aby wygenerowa\u0107 testowy zbi\u00f3r danych, mo\u017cna wykona\u0107 nast\u0119puj\u0105cy kod:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">df %\n  filter((product == \"A\" &amp; country == \"AI\") | product == \"B\") %&gt;% \n  mutate(value = rnorm(nrow(.)))<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 45 x 4\n#&gt;    product country  year    value\n#&gt;    &lt;chr&gt;   &lt;chr&gt;   &lt;int&gt;    &lt;dbl&gt;\n#&gt;  1 A       AI       2000 -2.05   \n#&gt;  2 A       AI       2001 -0.676  \n#&gt;  3 A       AI       2002  1.60   \n#&gt;  4 A       AI       2003 -0.353  \n#&gt;  5 A       AI       2004 -0.00530\n#&gt;  6 A       AI       2005  0.442  \n#&gt;  7 A       AI       2006 -0.610  \n#&gt;  8 A       AI       2007 -2.77   \n#&gt;  9 A       AI       2008  0.899  \n#&gt; 10 A       AI       2009 -0.106  \n#&gt; # \u2026 with 35 more rows<\/code><\/pre>\n<p><\/p>\n<p>Naszym zadaniem jest rozszerzenie zbioru danych, aby jedna kolumna zawiera\u0142a dane dla ka\u017cdej kombinacji produktu i kraju. W tym celu wystarczy przekaza\u0107 do argumentu <em>names_from<\/em> wektor, zawieraj\u0105cy nazwy \u0142\u0105czonych p\u00f3l.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">df %&gt;% pivot_wider(names_from = c(product, country),\n                 values_from = \"value\")<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 15 x 4\n#&gt;     year     A_AI    B_AI    B_EI\n#&gt;    &lt;int&gt;    &lt;dbl&gt;   &lt;dbl&gt;   &lt;dbl&gt;\n#&gt;  1  2000 -2.05     0.607   1.20  \n#&gt;  2  2001 -0.676    1.65   -0.114 \n#&gt;  3  2002  1.60    -0.0245  0.501 \n#&gt;  4  2003 -0.353    1.30   -0.459 \n#&gt;  5  2004 -0.00530  0.921  -0.0589\n#&gt;  6  2005  0.442   -1.55    0.594 \n#&gt;  7  2006 -0.610    0.380  -1.28  \n#&gt;  8  2007 -2.77     0.830   0.637 \n#&gt;  9  2008  0.899    0.0175 -1.30  \n#&gt; 10  2009 -0.106   -0.195   1.03  \n#&gt; # \u2026 with 5 more rows<\/code><\/pre>\n<p><\/p>\n<p>Mo\u017cesz r\u00f3wnie\u017c stosowa\u0107 specyfikacje do funkcji <code>pivot_wider()<\/code>. Ale przy podawaniu w <code>pivot_wider()<\/code> specyfikacja wykonuje przekszta\u0142cenie, przeciwne do <code>pivot_longer()<\/code>: tworzone s\u0105 kolumny, wskazane w <em>.name<\/em>, wykorzystuj\u0105c warto\u015bci z <em>.value<\/em> i innych kolumn.<\/p>\n<p><\/p>\n<p>Dla tego zbioru danych mo\u017cesz wygenerowa\u0107 niestandardow\u0105 specyfikacj\u0119, je\u015bli chcesz, aby ka\u017cda mo\u017cliwa kombinacja kraju i produktu mia\u0142a swoj\u0105 w\u0142asn\u0105 kolumn\u0119, a nie tylko te, kt\u00f3re s\u0105 obecne w danych:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">spec % \n  expand(product, country, .value = \"value\") %&gt;% \n  unite(\".name\", product, country, remove = FALSE)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 4 x 4\n#&gt;   .name product country .value\n#&gt;   &lt;chr&gt; &lt;chr&gt;   &lt;chr&gt;   &lt;chr&gt; \n#&gt; 1 A_AI  A       AI      value \n#&gt; 2 A_EI  A       EI      value \n#&gt; 3 B_AI  B       AI      value \n#&gt; 4 B_EI  B       EI      value<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">df %&gt;% pivot_wider(spec = spec) %&gt;% head()<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 6 x 5\n#&gt;    year     A_AI  A_EI    B_AI    B_EI\n#&gt;   &lt;int&gt;    &lt;dbl&gt; &lt;dbl&gt;   &lt;dbl&gt;   &lt;dbl&gt;\n#&gt; 1  2000 -2.05       NA  0.607   1.20  \n#&gt; 2  2001 -0.676      NA  1.65   -0.114 \n#&gt; 3  2002  1.60       NA -0.0245  0.501 \n#&gt; 4  2003 -0.353      NA  1.30   -0.459 \n#&gt; 5  2004 -0.00530    NA  0.921  -0.0589\n#&gt; 6  2005  0.442      NA -1.55    0.594<\/code><\/pre>\n<p><\/p>\n<h2 id=\"neskolko-prodvinutyh-primerov-raboty-s-novoy-koncepciey-tidyr\">Kilka zaawansowanych przyk\u0142ad\u00f3w pracy z now\u0105 koncepcj\u0105 tidyr<\/h2>\n<p><\/p>\n<h3 id=\"privedenie-dannyh-k-akkuratnomu-vidu-na-primere-nabora-dannyh-o-perepisi-dohoda-i-arendnoy-platy-v-ssha\">Uporz\u0105dkowanie danych na przyk\u0142adzie zestawu danych dotycz\u0105cego dochod\u00f3w i czynsz\u00f3w w USA<\/h3>\n<p><\/p>\n<p>Zbi\u00f3r danych <em>us_rent_income<\/em> zawiera informacje o \u015brednich dochodach i czynszach dla ka\u017cdego stanu w USA za 2017 rok (zbi\u00f3r danych jest dost\u0119pny w pakiecie <strong>tidycensus<\/strong>).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">us_rent_income\n#&gt; # A tibble: 104 x 5\n#&gt;    GEOID NAME       variable estimate   moe\n#&gt;                   \n#&gt;  1 01    Alabama    income      24476   136\n#&gt;  2 01    Alabama    rent          747     3\n#&gt;  3 02    Alaska     income      32940   508\n#&gt;  4 02    Alaska     rent         1200    13\n#&gt;  5 04    Arizona    income      27517   148\n#&gt;  6 04    Arizona    rent          972     4\n#&gt;  7 05    Arkansas   income      23789   165\n#&gt;  8 05    Arkansas   rent          709     5\n#&gt;  9 06    California income      29454   109\n#&gt; 10 06    California rent         1358     3\n#&gt; # \u2026 z 94 dodatkowymi wierszami<\/code><\/pre>\n<p><\/p>\n<p>W takiej formie, w jakiej s\u0105 przechowywane dane w zbiorze danych <em>us_rent_income<\/em> praca z nimi jest niezwykle niewygodna, dlatego chcieliby\u015bmy stworzy\u0107 zbi\u00f3r danych z kolumnami: <em>rent<\/em>, <em>rent_moe<\/em>, <em>come<\/em>, <em>income_moe<\/em>. Istnieje wiele sposob\u00f3w na stworzenie tej specyfikacji, ale najwa\u017cniejsze jest to, \u017ce musimy wygenerowa\u0107 ka\u017cd\u0105 kombinacj\u0119 warto\u015bci zmiennej i <em>estimate\/moe<\/em>, a nast\u0119pnie wygenerowa\u0107 nazw\u0119 kolumny.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">  spec % \n    expand(variable, .value = c(\"estimate\", \"moe\")) %&gt;% \n    mutate(\n      .name = paste0(variable, ifelse(.value == \"moe\", \"_moe\", \"\"))\n    )<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 4 x 3\n#&gt;   variable .value   .name     \n#&gt;   &lt;chr&gt;    &lt;chr&gt;    &lt;chr&gt;     \n#&gt; 1 income   estimate income    \n#&gt; 2 income   moe      income_moe\n#&gt; 3 rent     estimate rent      \n#&gt; 4 rent     moe      rent_moe<\/code><\/pre>\n<p><\/p>\n<p>Dostarczenie tej specyfikacji <code>pivot_wider()<\/code> daje nam wynik, kt\u00f3rego szukamy:<\/p>\n<p><\/p>\n<p><code>us_rent_income %&gt;% pivot_wider(spec = spec)<\/code><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 52 x 6\n#&gt;    GEOID NAME                 income income_moe  rent rent_moe\n#&gt;    &lt;chr&gt; &lt;chr&gt;                 &lt;dbl&gt;      &lt;dbl&gt; &lt;dbl&gt;    &lt;dbl&gt;\n#&gt;  1 01    Alabama               24476        136   747        3\n#&gt;  2 02    Alaska                32940        508  1200       13\n#&gt;  3 04    Arizona               27517        148   972        4\n#&gt;  4 05    Arkansas              23789        165   709        5\n#&gt;  5 06    California            29454        109  1358        3\n#&gt;  6 08    Colorado              32401        109  1125        5\n#&gt;  7 09    Connecticut           35326        195  1123        5\n#&gt;  8 10    Delaware              31560        247  1076       10\n#&gt;  9 11    District of Columbia  43198        681  1424       17\n#&gt; 10 12    Florida               25952         70  1077        3\n#&gt; # \u2026 with 42 more rows<\/code><\/pre>\n<p><\/p>\n<h3 id=\"vsemirnyy-bank\">Bank \u015awiatowy<\/h3>\n<p><\/p>\n<p>Czasami przekszta\u0142cenie zestawu danych do odpowiedniego formatu wymaga kilku krok\u00f3w.<br \/>\nZestaw danych <em>world_bank_pop<\/em> zawiera dane Banku \u015awiatowego dotycz\u0105ce populacji ka\u017cdego kraju w latach 2000-2018.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 1,056 x 20\n#&gt;    country indicator `2000` `2001` `2002` `2003`  `2004`  `2005`   `2006`\n#&gt;    &lt;chr&gt;   &lt;chr&gt;      &lt;dbl&gt;  &lt;dbl&gt;  &lt;dbl&gt;  &lt;dbl&gt;   &lt;dbl&gt;   &lt;dbl&gt;    &lt;dbl&gt;\n#&gt;  1 ABW     SP.URB.T\u2026 4.24e4 4.30e4 4.37e4 4.42e4 4.47e+4 4.49e+4  4.49e+4\n#&gt;  2 ABW     SP.URB.G\u2026 1.18e0 1.41e0 1.43e0 1.31e0 9.51e-1 4.91e-1 -1.78e-2\n#&gt;  3 ABW     SP.POP.T\u2026 9.09e4 9.29e4 9.50e4 9.70e4 9.87e+4 1.00e+5  1.01e+5\n#&gt;  4 ABW     SP.POP.G\u2026 2.06e0 2.23e0 2.23e0 2.11e0 1.76e+0 1.30e+0  7.98e-1\n#&gt;  5 AFG     SP.URB.T\u2026 4.44e6 4.65e6 4.89e6 5.16e6 5.43e+6 5.69e+6  5.93e+6\n#&gt;  6 AFG     SP.URB.G\u2026 3.91e0 4.66e0 5.13e0 5.23e0 5.12e+0 4.77e+0  4.12e+0\n#&gt;  7 AFG     SP.POP.T\u2026 2.01e7 2.10e7 2.20e7 2.31e7 2.41e+7 2.51e+7  2.59e+7\n#&gt;  8 AFG     SP.POP.G\u2026 3.49e0 4.25e0 4.72e0 4.82e0 4.47e+0 3.87e+0  3.23e+0\n#&gt;  9 AGO     SP.URB.T\u2026 8.23e6 8.71e6 9.22e6 9.77e6 1.03e+7 1.09e+7  1.15e+7\n#&gt; 10 AGO     SP.URB.G\u2026 5.44e0 5.59e0 5.70e0 5.76e0 5.75e+0 5.69e+0  4.92e+0\n#&gt; # \u2026 with 1,046 more rows, and 11 more variables: `2007` &lt;dbl&gt;,\n#&gt; #   `2008` &lt;dbl&gt;, `2009` &lt;dbl&gt;, `2010` &lt;dbl&gt;, `2011` &lt;dbl&gt;, `2012` &lt;dbl&gt;,\n#&gt; #   `2013` &lt;dbl&gt;, `2014` &lt;dbl&gt;, `2015` &lt;dbl&gt;, `2016` &lt;dbl&gt;, `2017` &lt;dbl&gt;<\/code><\/pre>\n<p><\/p>\n<p>Naszym celem jest stworzenie uporz\u0105dkowanego zestawu danych, w kt\u00f3rym ka\u017cda zmienna znajduje si\u0119 w osobnej kolumnie. Na razie nie jest jasne, jakie dok\u0142adnie kroki s\u0105 potrzebne, ale zaczniemy od najbardziej oczywistego problemu: rok jest roz\u0142o\u017cony na kilka kolumn.<\/p>\n<p><\/p>\n<p>Aby to naprawi\u0107, nale\u017cy u\u017cy\u0107 funkcji <code>pivot_longer()<\/code>.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">pop2 % \n  pivot_longer(`2000`:`2017`, names_to = \"year\")<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 19,008 x 4\n#&gt;    country indicator   year  value\n#&gt;    &lt;chr&gt;   &lt;chr&gt;       &lt;chr&gt; &lt;dbl&gt;\n#&gt;  1 ABW     SP.URB.TOTL 2000  42444\n#&gt;  2 ABW     SP.URB.TOTL 2001  43048\n#&gt;  3 ABW     SP.URB.TOTL 2002  43670\n#&gt;  4 ABW     SP.URB.TOTL 2003  44246\n#&gt;  5 ABW     SP.URB.TOTL 2004  44669\n#&gt;  6 ABW     SP.URB.TOTL 2005  44889\n#&gt;  7 ABW     SP.URB.TOTL 2006  44881\n#&gt;  8 ABW     SP.URB.TOTL 2007  44686\n#&gt;  9 ABW     SP.URB.TOTL 2008  44375\n#&gt; 10 ABW     SP.URB.TOTL 2009  44052\n#&gt; # \u2026 with 18,998 more rows<\/code><\/pre>\n<p><\/p>\n<p>Kolejnym krokiem jest rozwa\u017cenie zmiennej indicator.<br \/>\n<code>pop2 %&gt;% count(indicator)<\/code><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 4 x 2\n#&gt;   indicator       n\n#&gt;   &lt;chr&gt;       &lt;int&gt;\n#&gt; 1 SP.POP.GROW  4752\n#&gt; 2 SP.POP.TOTL  4752\n#&gt; 3 SP.URB.GROW  4752\n#&gt; 4 SP.URB.TOTL  4752<\/code><\/pre>\n<p><\/p>\n<p>Gdzie SP.POP.GROW to wzrost populacji, SP.POP.TOTL to ca\u0142kowita liczba ludno\u015bci, a SP.URB. * to samo, ale tylko dla obszar\u00f3w miejskich. Podzielmy te warto\u015bci na dwie zmienne: area \u2014 obszar (total lub urban) oraz zmienn\u0105 zawieraj\u0105c\u0105 faktyczne dane (population lub growth):<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">pop3 % \n  separate(indicator, c(NA, \"area\", \"variable\") )<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 19,008 x 5\n#&gt;    country area  variable year  value\n#&gt;    &lt;chr&gt;   &lt;chr&gt; &lt;chr&gt;    &lt;chr&gt; &lt;dbl&gt;\n#&gt;  1 ABW     URB   TOTL     2000  42444\n#&gt;  2 ABW     URB   TOTL     2001  43048\n#&gt;  3 ABW     URB   TOTL     2002  43670\n#&gt;  4 ABW     URB   TOTL     2003  44246\n#&gt;  5 ABW     URB   TOTL     2004  44669\n#&gt;  6 ABW     URB   TOTL     2005  44889\n#&gt;  7 ABW     URB   TOTL     2006  44881\n#&gt;  8 ABW     URB   TOTL     2007  44686\n#&gt;  9 ABW     URB   TOTL     2008  44375\n#&gt; 10 ABW     URB   TOTL     2009  44052\n#&gt; # \u2026 with 18,998 more rows<\/code><\/pre>\n<p><\/p>\n<p>Teraz musimy tylko podzieli\u0107 zmienn\u0105 variable na dwie kolumny:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">pop3 %&gt;% \n  pivot_wider(names_from = variable, values_from = value)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 9,504 x 5\n#&gt;    country area  year   TOTL    GROW\n#&gt;    &lt;chr&gt;   &lt;chr&gt; &lt;chr&gt; &lt;dbl&gt;   &lt;dbl&gt;\n#&gt;  1 ABW     URB   2000  42444  1.18  \n#&gt;  2 ABW     URB   2001  43048  1.41  \n#&gt;  3 ABW     URB   2002  43670  1.43  \n#&gt;  4 ABW     URB   2003  44246  1.31  \n#&gt;  5 ABW     URB   2004  44669  0.951 \n#&gt;  6 ABW     URB   2005  44889  0.491 \n#&gt;  7 ABW     URB   2006  44881 -0.0178\n#&gt;  8 ABW     URB   2007  44686 -0.435 \n#&gt;  9 ABW     URB   2008  44375 -0.698 \n#&gt; 10 ABW     URB   2009  44052 -0.731 \n#&gt; # \u2026 with 9,494 more rows<\/code><\/pre>\n<p><\/p>\n<h3 id=\"spisok-kontaktov\">Lista kontakt\u00f3w<\/h3>\n<p><\/p>\n<p>Ostatni przyk\u0142ad, wyobra\u017a sobie, \u017ce masz list\u0119 kontakt\u00f3w, kt\u00f3r\u0105 skopiowa\u0142e\u015b i wklei\u0142e\u015b ze strony internetowej:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">contacts &lt;- tribble(\n  ~field, ~value,\n  &quot;name&quot;, &quot;Jiena McLellan&quot;,\n  &quot;company&quot;, &quot;Toyota&quot;, \n  &quot;name&quot;, &quot;John Smith&quot;, \n  &quot;company&quot;, &quot;google&quot;, \n  &quot;email&quot;, &quot;john@google.com&quot;,\n  &quot;name&quot;, &quot;Huxley Ratcliffe&quot;\n)<\/code><\/pre>\n<p><\/p>\n<p>Zestawienie tej listy w formie tabeli jest do\u015b\u0107 trudne, poniewa\u017c nie ma zmiennej, kt\u00f3ra identyfikuje, kt\u00f3re dane nale\u017c\u0105 do kt\u00f3rego kontaktu. Mo\u017cemy to naprawi\u0107, zauwa\u017caj\u0105c, \u017ce dane dla ka\u017cdego nowego kontaktu zaczynaj\u0105 si\u0119 od imienia (\"name\"), dlatego mo\u017cemy stworzy\u0107 unikalny identyfikator i zwi\u0119ksza\u0107 go o jeden za ka\u017cdym razem, gdy w kolumnie field pojawia si\u0119 warto\u015b\u0107 \u201ename\u201d:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">contacts % \n  mutate(\n    person_id = cumsum(field == \"name\")\n  )\ncontacts<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 6 x 3\n#&gt;   field   value            person_id\n#&gt;   &lt;chr&gt;   &lt;chr&gt;                &lt;int&gt;\n#&gt; 1 name    Jiena McLellan           1\n#&gt; 2 company Toyota                   1\n#&gt; 3 name    John Smith               2\n#&gt; 4 company google                   2\n#&gt; 5 email   john@google.com          2\n#&gt; 6 name    Huxley Ratcliffe         3<\/code><\/pre>\n<p><\/p>\n<p>Teraz, gdy mamy unikalny identyfikator dla ka\u017cdego kontaktu, mo\u017cemy obr\u00f3ci\u0107 pole i warto\u015b\u0107 w kolumny:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">contacts %&gt;% \n  pivot_wider(names_from = field, values_from = value)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">#&gt; # A tibble: 3 x 4\n#&gt;   person_id name             company email          \n#&gt;       &lt;int&gt; &lt;chr&gt;            &lt;chr&gt;   &lt;chr&gt;          \n#&gt; 1         1 Jiena McLellan   Toyota  &lt;NA&gt;           \n#&gt; 2         2 John Smith       google  john@google.com\n#&gt; 3         3 Huxley Ratcliffe &lt;NA&gt;    &lt;NA&gt;<\/code><\/pre>\n<p><\/p>\n<h2 id=\"zaklyuchenie\">Podsumowanie<\/h2>\n<p><\/p>\n<p>Osobi\u015bcie s\u0105dz\u0119, \u017ce nowa koncepcja <strong>tidyr<\/strong> jest naprawd\u0119 bardziej intuicyjna i znacznie przewy\u017csza funkcje przestarza\u0142e <code>spread()<\/code> i <code>gather()<\/code>. Mam nadziej\u0119, \u017ce ten artyku\u0142 pom\u00f3g\u0142 ci zrozumie\u0107 <code>pivot_longer()<\/code> i <code>pivot_wider()<\/code>.<\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/444622\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0430\u043a\u0435\u0442 tidyr \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u044f\u0434\u0440\u043e \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 R \u2014 tidyverse. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 \u2014 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e\u043c\u0443 \u0432\u0438\u0434\u0443. \u041d\u0430 \u0425\u0430\u0431\u0440\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u0441\u0432\u044f\u0449\u0451\u043d\u043d\u0430\u044f \u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043f\u0430\u043a\u0435\u0442\u0443, \u043d\u043e \u0434\u0430\u0442\u0438\u0440\u0443\u044e\u0435\u0442\u0441\u044f \u043e\u043d\u0430 2015 \u0433\u043e\u0434\u043e\u043c. \u0410 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043e \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043d\u0435\u0439 \u043d\u0430\u0437\u0430\u0434 \u0441\u043e\u043e\u0431\u0449\u0438\u043b \u0435\u0433\u043e \u0430\u0432\u0442\u043e\u0440 \u0425\u0435\u0434\u043b\u0438 \u0412\u0438\u043a\u0445\u0435\u043c. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":76292,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-76291","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0430\u043a\u0435\u0442 tidyr \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u044f\u0434\u0440\u043e \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 R \u2014 tidyverse. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 \u2014 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e\u043c\u0443 \u0432\u0438\u0434\u0443. \u041d\u0430 \u0425\u0430\u0431\u0440\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/r-paket-tidyr-i-ego-novye-funkczii-pivot_longer-i-pivot_wider\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47R \u043f\u0430\u043a\u0435\u0442 tidyr \u0438 \u0435\u0433\u043e \u043d\u043e\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 pivot_longer \u0438 pivot_wider | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0430\u043a\u0435\u0442 tidyr \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u044f\u0434\u0440\u043e \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 R \u2014 tidyverse. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 \u2014 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e\u043c\u0443 \u0432\u0438\u0434\u0443. \u041d\u0430 \u0425\u0430\u0431\u0440\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/r-paket-tidyr-i-ego-novye-funkczii-pivot_longer-i-pivot_wider\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-04-01T11:42:28+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-04-01T11:42:28+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Pakiet R tidyr i jego nowe funkcje pivot_longer i pivot_wider | ProHoster","description":"Pakiet tidyr jest cz\u0119\u015bci\u0105 jednej z najpopularniejszych bibliotek w j\u0119zyku R \u2014 tidyverse. Jego g\u0142\u00f3wnym celem jest przekszta\u0142canie danych do uporz\u0105dkowanej formy. Na Habrze.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/r-paket-tidyr-i-ego-novye-funkczii-pivot_longer-i-pivot_wider","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47R \u043f\u0430\u043a\u0435\u0442 tidyr \u0438 \u0435\u0433\u043e \u043d\u043e\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 pivot_longer \u0438 pivot_wider | ProHoster","og:description":"\u041f\u0430\u043a\u0435\u0442 tidyr \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u044f\u0434\u0440\u043e \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 R \u2014 tidyverse. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 \u2014 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e\u043c\u0443 \u0432\u0438\u0434\u0443. \u041d\u0430 \u0425\u0430\u0431\u0440\u0435.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/r-paket-tidyr-i-ego-novye-funkczii-pivot_longer-i-pivot_wider","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-04-01T11:42:28+00:00","article:modified_time":"2020-04-01T11:42:28+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"76291","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 17:39:23","updated":"2022-09-28 03:21:22","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/76291","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=76291"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/76291\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/76292"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=76291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=76291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=76291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}