Agregatul care rulează pe matrice largi este nevoie de loooong; Utilizați în schimb aplicații cuibărite sau tabele de date!

URMĂREȘTE-NE
16,065FaniÎmi place
1,142CititoriConectați-vă

(Acest articol a fost publicat pentru prima dată pe gacatagși a contribuit cu drag la R-Bloggers). (Puteți raporta problema despre conținutul de pe această pagină aici)


Doriți să vă împărtășiți conținutul pe R-Bloggers? Faceți clic aici dacă aveți un blog sau aici dacă nu.

agregat funcția poate fi foarte utilă în R, permițând unuia să ruleze o funcție (de exemplu medie) în cadrul grupurilor de rânduri, în fiecare coloană într-o matrice/cadru de date și organizează rezultatele într-un tabel ușor de citit. Cu toate acestea, funcția durează mult timp pentru a rula pentru matrici foarte largi și cadre de date, unde numărul coloanelor este mare. În această postare demonstrez problema și arăt câteva soluții frumoase care cel puțin pentru exemplu reduce timpul la 15% și chiar mai puțin, comparativ cu timpul de rulare al funcției agregate.

Am creat mai întâi o matrice largă cu 100 de rânduri și 10.000 de coloane, adăpostind 1.000.000 de valori generate aleatoriu folosind distribuția normală.

# Necesitatea de a evita matricile largi (cu o mulțime de coloane)!
matwide = matrice (rnorm (1e+06), nrow = 100, ncol = 10000)

# Transformă matricea în cadrul datelor
dfwide = as.data.frame (matwide)

Am folosit funcția agregată pentru a lua media în cadrul grupurilor de rânduri, pentru fiecare coloană! Mi -am dat seama că funcția agregată durează aproximativ 4 secunde.

t1 = sys.time ()
agregate = agregat (dfwide, list (rep (1:10, fiecare = 10)), medie)
(timedifaggr = difTime (sys.time (), t1, unități = „sec”))
#Diferența de timp de 3.807029 sec

Iată pumnul 5 coloane și rândurile cadrului de date rezultat și dimensiunile acestuia.

agresuri (1: 5,1: 5)
# Grup.1 v1 v2 v3 v4
#1 1 0.008815372 0.56920407 0.2195522 0.68183883
#2 2 0.046319580 0.07915253 0.2732586 0.30970451
#3 3 0.154718798 -0.09157008 -0.3676212 -0.02970137
#4 4 0.491208585 0.53066464 -0.1407269 0.49633703
#5 5 -0.397868879 -0.09793382 0.4154764 -0.17150871

dim (agres)
#(1) 10 10001

Apoi am folosit o funcție „Aplicare” cuibărită (din punct de vedere tehnic a tapply în interiorul unui aplicați Funcție) Abordare pentru a rula aceeași analiză. A durat semnificativ mai puțin timp (aproximativ o jumătate de secundă).

t1 = sys.time ()
NestApplyRes = Appl (dfwide, 2, funcție (x) {
return (tapply (x, rep (1:10, fiecare = 10), medie))})
NestApplyRes = data.frame (grup.1 = rownomes (NestApplyres),
NestApplyres)
(timedifnest = difTime (sys.time (), t1, unități = „sec”))
#Diferență de timp de 0,5010331 sec

#Verificați dacă oferă exact același rezultat ca agregat
toate (agres == NestApplyres)
#(1) Adevărat

În cele din urmă, am folosit tabelele de date așa cum s -a sugerat de puțini pe unele forumuri. A durat și mai puțin timp pentru a alerga; aproximativ 0,26 secunde.


bibliotecă (data.table)
t1 = sys.time ()
#Convert la date.Table și COMPUTE mijloace în ordine-majoră coloană (cum ar fi agregat)
dtres <- as.data.table (dfwide) (, lapply (.sd, funcție (x) medie (x)), by =. (grup.1 = rep (1:10, fiecare = 10)))
dtres = as.data.frame (dtres)
(timedifdt = difTime (sys.time (), t1, unități = „secs”))
#Diferență de timp de 0,268255 sec

toate (agres == dtres)
#ADEVĂRAT

De asemenea, am reprezentat timpul de rulare al fiecăreia dintre abordări!


jpeg („timedif.jpg”, res = 300, lățime = 800, înălțime = 800)
par (mar = c (6,5, 2,5, 1,5, 0,5))
barplot (înălțime = as.numeric (c (timedifaggr, timedifnest, timedifdt)),
nume.arg = c („agregat”, „aplicare cuibărit”, „tabel de date”),
las = 2, ylim = c (0,4), col = Heat.colors (3), ylab = „sec”)
dev.off ()

Deci, acum mă voi gândi de două ori înainte să folosesc agregat Funcția 😒.

Dominic Botezariu
Dominic Botezariuhttps://www.noobz.ro/
Creator de site și redactor-șef.

Cele mai noi știri

Pe același subiect

LĂSAȚI UN MESAJ

Vă rugăm să introduceți comentariul dvs.!
Introduceți aici numele dvs.