ProHoster > Блог > басқарма > R бумасы tidyr және оның жаңа функциялары pivot_longer және pivot_wider
R бумасы tidyr және оның жаңа функциялары pivot_longer және pivot_wider
Пакет ұқыпты R тіліндегі ең танымал кітапханалардың бірінің өзегіне енгізілген - ұқыптылық.
Пакеттің негізгі мақсаты – деректерді нақты пішінге келтіру.
Habré сайтында қазірдің өзінде қол жетімді жариялау осы пакетке арналған, бірақ ол 2015 жылдан басталады. Мен сізге бірнеше күн бұрын оның авторы Хедли Уикхэм жариялаған ең өзекті өзгерістер туралы айтқым келеді.
S.J.K.: gather() және spread() ескіреді ме?
Хэдли Уикхэм: Белгілі бір дәрежеде. Біз бұдан былай бұл функцияларды пайдалануды ұсынбаймыз және олардағы қателерді түзетеміз, бірақ олар ағымдағы күйінде пакетте болуын жалғастырады.
Мазмұны
Егер сіз деректерді талдауға қызығушылық танытсаңыз, сізді мені қызықтыруы мүмкін жеделхат и YouTube арналар. Мазмұнның көп бөлігі R тіліне арналған.
Максат ұқыпты — деректерді ұқыпты деп аталатын пішінге келтіруге көмектеседі. Таза деректер мына жердегі деректер:
Әрбір айнымалы бағанда орналасқан.
Әрбір бақылау жол болып табылады.
Әрбір мән ұяшық болып табылады.
Талдау жүргізген кезде жинақы деректерде берілген деректермен жұмыс істеу әлдеқайда жеңіл және ыңғайлы.
Tidyr пакетіне кіретін негізгі функциялар
tidyr кестелерді түрлендіруге арналған функциялар жиынтығын қамтиды:
fill() — бағандағы жетіспейтін мәндерді алдыңғы мәндермен толтыру;
separate() — бөлгіштің көмегімен бір өрісті бірнешеге бөледі;
unite() — бірнеше өрістерді бір жерге біріктіру операциясын, функцияның кері әрекетін орындайды separate();
pivot_longer() — деректерді кең форматтан ұзын форматқа түрлендіретін функция;
pivot_wider() - деректерді ұзын форматтан кең форматқа түрлендіретін функция. Функциямен орындалатын жұмыстың кері әрекеті pivot_longer().
gather()ескірген — деректерді кең форматтан ұзын форматқа түрлендіретін функция;
spread()ескірген - деректерді ұзын форматтан кең форматқа түрлендіретін функция. Функциямен орындалатын жұмыстың кері әрекеті gather().
Деректерді кең форматтан ұзын форматқа және керісінше түрлендірудің жаңа тұжырымдамасы
Бұрын мұндай түрлендіру үшін функциялар қолданылған gather() и spread(). Осы функциялардың өмір сүрген жылдарында көптеген пайдаланушылар үшін, соның ішінде пакет авторы үшін бұл функциялардың атаулары мен олардың дәлелдері анық емес екені белгілі болды және оларды табуда және осы функциялардың қайсысы түрлендіретінін түсінуде қиындықтар туғызды. кең пішімнен ұзын пішімге дейінгі күн шеңбері және керісінше.
Осыған байланысты, в ұқыпты Күн кадрларын түрлендіруге арналған екі жаңа маңызды функция қосылды.
Жаңа мүмкіндіктер pivot_longer() и pivot_wider() пакеттегі кейбір мүмкіндіктерден шабыттанды cдата, Джон Маунт пен Нина Зумель жасаған.
tidyr 0.8.3.9000 ең соңғы нұсқасын орнату
Буманың жаңа, ең соңғы нұсқасын орнату үшін ұқыпты0.8.3.9000, жаңа мүмкіндіктер қолжетімді болса, келесі кодты пайдаланыңыз.
devtools::install_github("tidyverse/tidyr")
Жазу кезінде бұл функциялар GitHub-тағы пакеттің әзірлеуші нұсқасында ғана қолжетімді.
Жаңа мүмкіндіктерге көшу
Шындығында, ескі сценарийлерді жаңа функциялармен жұмыс істеуге көшіру қиын емес, жақсы түсіну үшін мен ескі функциялардың құжаттамасынан мысал аламын және жаңаларын пайдалану арқылы бірдей әрекеттердің қалай орындалатынын көрсетемін. pivot_*() функциялары.
Кең пішімді ұзын форматқа түрлендіру.
Жинау функциясының құжаттамасындағы мысал код
# 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")
Ұзын форматты кең форматқа түрлендіру.
Спрэд функциясының құжаттамасындағы мысал код
# old
stocks_spread <- stocks_gather %>% spread(key = stock,
value = price)
# new
stock_wide <- stocks_long %>% pivot_wider(names_from = "stock",
values_from = "price")
Өйткені жұмыс істеудің жоғарыдағы мысалдарында pivot_longer() и pivot_wider(), бастапқы кестеде акциялар аргументтер тізімінде ешқандай баған жоқ атаулары и мәндері_ олардың аттары тырнақшаға алынуы керек.
Жаңа тұжырымдамамен жұмыс істеуге қалай ауысу керектігін анықтауға көмектесетін кесте ұқыпты.
Автордан ескерту
Төмендегі мәтіннің барлығы бейімделген, тіпті тегін аударма дер едім виньеткалар tidyverse кітапханасының ресми веб-сайтынан.
Деректерді кең форматтан ұзын форматқа түрлендірудің қарапайым мысалы
pivot_longer () — бағандар санын азайту және жолдар санын көбейту арқылы деректер жиынын ұзартады.
Мақалада келтірілген мысалдарды іске қосу үшін алдымен қажетті пакеттерді қосу керек:
library(tidyr)
library(dplyr)
library(readr)
Бізде (басқа нәрселермен қатар) адамдардың діні мен жылдық табысы туралы сұраған сауалнама нәтижелері бар кесте бар делік:
Бұл кесте респонденттердің дін деректерін жолдар бойынша қамтиды және кіріс деңгейлері баған атаулары бойынша шашыраңқы. Әрбір санаттағы респонденттердің саны дін мен кіріс деңгейінің қиылысындағы ұяшық мәндерінде сақталады. Кестені ұқыпты, дұрыс пішімге келтіру үшін оны пайдалану жеткілікті pivot_longer():
Бірінші аргумент қамыт, қандай бағандарды біріктіру керектігін сипаттайды. Бұл жағдайда басқа барлық бағандар уақыт.
дәлел атаулары біз біріктірген бағандардың атауларынан жасалатын айнымалының атын береді.
мәндері_ біріктірілген бағандардың ұяшықтарының мәндерінде сақталған деректерден жасалатын айнымалының атын береді.
Ерекшеліктер
Бұл пакеттің жаңа функционалдығы ұқыпты, ол бұрынғы функциялармен жұмыс істеу кезінде бұрын қол жетімді емес еді.
Спецификация - бұл деректер жақтауы, оның әрбір жолы жаңа шығыс күн жақтауындағы бір бағанға және келесіден басталатын екі арнайы бағанға сәйкес келеді:
аты бастапқы баған атауын қамтиды.
.мән ұяшық мәндерін қамтитын баған атауын қамтиды.
Спецификацияның қалған бағандары жаңа бағанның қысылған бағандардың атауын қалай көрсететінін көрсетеді аты.
Спецификация баған атауында сақталған метадеректерді сипаттайды, әрбір баған үшін бір жол және әр айнымалы үшін бір баған бар, баған атауымен біріктірілген, бұл анықтама қазіргі уақытта түсініксіз болып көрінуі мүмкін, бірақ бірнеше мысалдарды қарағаннан кейін ол көп болады. анық.
Сипаттаманың мәні мынада: түрлендірілетін деректер кадры үшін жаңа метадеректерді шығарып алуға, өзгертуге және анықтауға болады.
Кестені кең пішімнен ұзын пішімге түрлендіру кезінде сипаттамалармен жұмыс істеу үшін функцияны пайдаланыңыз pivot_longer_spec().
Бұл функция қалай жұмыс істейді, ол кез келген күн кадрын алады және оның метадеректерін жоғарыда сипатталған тәсілмен жасайды.
Мысал ретінде пакетпен қамтамасыз етілген who деректер жинағын алайық ұқыпты. Бұл деректер жинағында туберкулез ауруы туралы халықаралық денсаулық сақтау ұйымы ұсынған ақпарат бар.
who
#> # A tibble: 7,240 x 60
#> country iso2 iso3 year new_sp_m014 new_sp_m1524 new_sp_m2534
#> <chr> <chr> <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
#> # … with 7,230 more rows, and 53 more variables
Оның спецификациясын құрастырайық.
spec <- who %>%
pivot_longer_spec(new_sp_m014:newrel_f65, values_to = "count")
өрістер ел, iso2, iso3 қазірдің өзінде айнымалылар. Біздің міндетіміз - бағандарды аудару new_sp_m014 туралы newrel_f65.
Бұл бағандардың атаулары келесі ақпаратты сақтайды:
Префикс new_ бағанда туберкулездің жаңа жағдайлары туралы деректер бар екенін көрсетеді, ағымдағы күндік жақтауда тек жаңа аурулар туралы ақпарат бар, сондықтан ағымдағы контексте бұл префикс ешқандай мағына бермейді.
Соңында, біз жасаған спецификацияны бастапқы күн шеңберіне қолдану үшін кім аргумент қолдануымыз керек ерекшелігі функцияда 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 rows
Біз жасаған барлық әрекеттерді схемалық түрде келесідей бейнелеуге болады:
Бірнеше мәндерді қолданатын спецификация (.value)
Жоғарыдағы мысалда спецификация бағаны .мән тек бір мәнді қамтиды, көп жағдайда солай болады.
Бірақ кейде мәндерде әртүрлі деректер түрлері бар бағандардан деректерді жинау қажет болғанда жағдай туындауы мүмкін. Бұрынғы функцияны пайдалану spread() мұны істеу өте қиын болар еді.
Төмендегі мысалдан алынған виньеткалар пакетке деректер кестесі.
Жасалған күн шеңбері әр жолда бір отбасының балалары туралы деректерді қамтиды. Отбасында бір немесе екі бала болуы мүмкін. Әрбір бала үшін деректер туған күні мен жынысы бойынша беріледі, ал әрбір балаға арналған деректер жеке бағандарда беріледі, біздің міндетіміз - бұл деректерді талдау үшін дұрыс пішімге келтіру.
Бізде әр бала туралы ақпарат бар екі айнымалы мән бар екенін ескеріңіз: олардың жынысы және туған күні (префиксі бар бағандар Доп туған күні, префиксі бар бағандар бар жыныс баланың жынысын қамтиды). Күтілетін нәтиже - олар бөлек бағандарда пайда болуы керек. Біз мұны баған болатын спецификацияны жасау арқылы жасай аламыз .value екі түрлі мағынаға ие болады.
spec <- family %>%
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 2
Сонымен, жоғарыдағы кодпен орындалатын әрекеттерді кезең-кезеңімен қарастырайық.
pivot_longer_spec(-family) — отбасы бағанынан басқа барлық бар бағандарды қысатын спецификация жасаңыз.
separate(col = name, into = c(".value", "child")) - бағанды бөлу аты, онда астын сызу арқылы және алынған мәндерді бағандарға енгізу арқылы бастапқы өрістердің атаулары бар .мән и бала.
mutate(child = parse_number(child)) — өріс мәндерін түрлендіру бала мәтіннен сандық деректер түріне дейін.
Енді алынған спецификацияны бастапқы деректер фрейміне қолданып, кестені қажетті пішінге келтіре аламыз.
Біз аргументті қолданамыз na.rm = TRUE, себебі деректердің ағымдағы пішіні жоқ бақылаулар үшін қосымша жолдарды жасауға мәжбүр етеді. Өйткені 2-отбасында бір ғана бала бар, na.rm = TRUE 2-отбасының шығысында бір жол болатынына кепілдік береді.
Күн жиектерін ұзын пішімнен кең пішімге түрлендіру
pivot_wider() - кері түрлендіру болып табылады және керісінше жолдар санын азайту арқылы күн кадрының бағандарының санын көбейтеді.
Трансформацияның бұл түрі деректерді нақты пішінге келтіру үшін өте сирек қолданылады, дегенмен бұл әдіс презентацияларда пайдаланылатын жиынтық кестелерді құру немесе кейбір басқа құралдармен біріктіру үшін пайдалы болуы мүмкін.
Іс жүзінде функциялар pivot_longer() и pivot_wider() симметриялы және бір-біріне кері әрекеттер жасайды, яғни: df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) и df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) бастапқы df қайтарады.
Кестені кең форматқа түрлендірудің қарапайым мысалы
Функцияның қалай жұмыс істейтінін көрсету үшін pivot_wider() деректер жинағын қолданамыз балықтармен кездесулер, ол әртүрлі станциялар өзен бойындағы балықтардың қозғалысын қалай тіркейтіні туралы ақпаратты сақтайды.
#> # 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 rows
Көп жағдайда бұл кесте ақпаратты әр станцияға арналған ақпаратты бөлек бағанда ұсынсаңыз, пайдалану оңайырақ болады.
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
#> <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 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
#> # … with 9 more rows, and 1 more variable: MAW <int>
Бұл деректер жинағы станциямен балық анықталған кезде ғана ақпаратты жазады, яғни. егер қандай да бір станция қандай да бір балықты тіркемеген болса, онда бұл деректер кестеде болмайды. Бұл шығыс NA толтырылатынын білдіреді.
Дегенмен, бұл жағдайда біз жазбаның болмауы балықтың көрмегенін білдіретінін білеміз, сондықтан біз аргументті пайдалана аламыз. мәндерді_толтыру функцияда pivot_wider() және осы жетіспейтін мәндерді нөлдермен толтырыңыз:
Бірнеше бастапқы айнымалылардан баған атауын жасау
Бізде өнімнің, елдің және жылдың тіркесімін қамтитын кесте бар деп елестетіп көріңіз. Сынақ күні шеңберін жасау үшін келесі кодты іске қосуға болады:
df <- expand_grid(
product = c("A", "B"),
country = c("AI", "EI"),
year = 2000:2014
) %>%
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 rows
Біздің міндетіміз - бір баған өнімнің және елдің әрбір тіркесімі үшін деректерді қамтитындай деректер шеңберін кеңейту. Бұл әрекетті орындау үшін, дәлелдеуге жеткілікті атаулары біріктірілетін өрістердің атауларын қамтитын вектор.
Сондай-ақ, спецификацияларды функцияға қолдануға болады pivot_wider(). Бірақ тапсырылған кезде pivot_wider() спецификация қарама-қарсы түрлендіруді жасайды pivot_longer(): ішінде көрсетілген бағандар аты, мәнін пайдалану .мән және басқа бағандар.
Бұл деректер жиыны үшін әрбір ықтимал ел мен өнім комбинациясының деректерде барлар ғана емес, өз бағандары болуын қаласаңыз, теңшелетін спецификацияны жасай аласыз:
#> # 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 value
df %>% 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.594
Жаңа tidyr тұжырымдамасымен жұмыс істеудің бірнеше жетілдірілген мысалдары
Мысал ретінде АҚШ-тағы халық санағының кірісі мен жалдау деректер жинағын пайдаланып деректерді тазалау.
Деректер жинағы бізге_ренттен_кіріс 2017 жылға арналған АҚШ-тағы әрбір штат үшін орташа табыс пен жалдау туралы ақпаратты қамтиды (деректер жиынтығы пакетте қол жетімді реттік санақ).
us_rent_income
#> # A tibble: 104 x 5
#> GEOID NAME variable estimate moe
#> <chr> <chr> <chr> <dbl> <dbl>
#> 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
#> # … with 94 more rows
Деректер жиынында деректер сақталатын пішінде бізге_ренттен_кіріс олармен жұмыс істеу өте ыңғайсыз, сондықтан біз бағандары бар деректер жинағын жасағымыз келеді: жалға алу, rent_moe, келу, кіріс_мое. Бұл спецификацияны жасаудың көптеген жолдары бар, бірақ бастысы - біз айнымалы мәндердің әрбір комбинациясын жасауымыз керек және бағалау/мсодан кейін баған атауын жасаңыз.
Кейде деректер жинағын қажетті пішінге келтіру бірнеше қадамдарды қажет етеді.
Деректер жинағы әлемдік_банк_поп Дүниежүзілік банктің 2000-2018 жылдар аралығындағы әр елдің халқы туралы мәліметтерін қамтиды.
Біздің мақсатымыз - әр айнымалы өз бағанында ұқыпты деректер жинағын жасау. Қандай қадамдар қажет екені белгісіз, бірақ біз ең айқын мәселеден бастаймыз: жыл бірнеше бағандарға таралады.
Мұны түзету үшін функцияны пайдалану керек pivot_longer().
Келесі қадам - индикатор айнымалысын қарау. 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 4752
Мұндағы SP.POP.GROW - халық санының өсуі, SP.POP.TOTL - жалпы халық саны және SP.URB. * бірдей нәрсе, бірақ тек қалалық жерлер үшін. Бұл мәндерді екі айнымалыға бөлейік: аудан - аудан (жалпы немесе қалалық) және нақты деректерді қамтитын айнымалы (халық немесе өсім):
Бұл тізімді кестелеу өте қиын, себебі қандай деректер қай контактіге тиесілі екенін анықтайтын айнымалы жоқ. Мұны әрбір жаңа контактінің деректері «атаудан» басталатынын ескеру арқылы түзете аламыз, осылайша біз бірегей идентификатор жасай аламыз және өріс бағанында «аты» мәні болған сайын оны бір есе арттыра аламыз:
#> # 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 [email protected] 2
#> 6 name Huxley Ratcliffe 3
Енді бізде әрбір контакт үшін бірегей идентификатор бар, біз өріс пен мәнді бағандарға айналдыра аламыз:
#> # 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 [email protected]
#> 3 3 Huxley Ratcliffe <NA> <NA>
қорытынды
Менің жеке пікірім - бұл жаңа тұжырымдама ұқыпты шынымен интуитивті және бұрынғы функцияларға қарағанда функционалдығы жағынан айтарлықтай жоғары spread() и gather(). Бұл мақала сізге түсінуге көмектесті деп үміттенемін pivot_longer() и pivot_wider().