Küsimus:
Libiseva akna keskmine R-s
T-Burns
2010-09-24 19:41:32 UTC
view on stackexchange narkive permalink

Mul on väärtuste vektor, mille kohta tahaksin teatada väiksema slaidi akende keskmise.

Näiteks järgmiste väärtuste vektori puhul:

  4, 5, 7, 3, 9, 8  

Akna suurus 3 ja slaid 2 teevad järgmist:

  ( 4 + 5 + 7) / 3 = 5,33 (7 + 3 + 9) / 3 = 6,33 (9 + 8) / 3 = 5,67  

Ja tagastage nende väärtuste vektor:

  5.33, 6.33, 5.67  

Kas on mõni lihtne funktsioon, mis minu jaoks seda teeb? Kui see tagastaks ka akna indeksid, oleks see lisaboonus. Selles näites oleks see 1,3,5

Kas olete seda näinud (http://rss.acs.unt.edu/Rdoc/library/TTR/html/MovingAverages.html)?
Kas saaksite selle "slaidi" idee kohta tausta anda?
@J.M - ma polnud seda teinud! Aitäh! Näen, kuidas see töötab.
@Shane - jah! Mul on kahju, et see polnud selge. Slaid on positsioonide / indeksite arv, mida liigutate järgmise keskmiste akna arvutamise alustamiseks. Nii et selle asemel, et järgmine aken algab pärast viimase lõppu, on teatud kattuvus, kui slaid on väiksem kui akna suurus. Idee on andmepunkte natuke siluda.
Aitäh, mul oli sama küsimus. Nüüd leidsin, et funktsioon "rollapply" on kasulik.
Seitse vastused:
#1
+25
Gavin Simpson
2010-09-24 20:36:42 UTC
view on stackexchange narkive permalink

Funktsioon rollapply viib teid pakettloomaaias lähedale:

  > nõuda (loomaaed) > TS <- loomaaed (c (4, 5, 7, 3, 9, 8)) > rollapply (TS, laius = 3, by = 2, FUN = keskmine, joondus = "vasak") 1 3 5.333333 6.333333  

See lihtsalt ei arvuta viimane väärtus teie jaoks, kuna see ei sisalda kolme tähelepanekut. Võib-olla on see teie tegeliku probleemi jaoks piisav? Pange tähele ka seda, et tagastatud objekti indeksid soovite tagastatava vektori nimed .

Teie näites oletatakse, et viimases aknas on jälgimata 0 . Võib olla kasulikum või realistlikum, kui NA -ga klõpsate puuduva teabe tähistamiseks ja käskite mean puuduvate väärtuste käsitsemiseks. Sel juhul on meil viimase akna väärtusena (8 + 9) / 2.

  > TS <- loomaaed (c (4, 5, 7, 3, 9, 8, NA )) > korduvalt (TS, laius = 3, by = 2, FUN = keskmine, na.rm = TRUE, joondus = "vasak") 1 3 5 5.333333 6.333333 8.500000  
BTW, kirjutasin kunagi selle funktsiooni kasutamisest mõiste "kvantli löss" rakendamiseks: http://www.r-statistics.com/2010/04/quantile-loess-combining-a-moving-quantile-window -leess-r-funktsiooniga /
Vastuse viimase elemendi saamiseks võite x-i lõppu lisada 0 ("x <-c (x, 0)").
@mbq; see teeb tugeva eelduse, et vaatlus on 0. Olin seda mõtet mõlgutanud ja T-Burns teeb sama eelduse (tähelepanuta jäetud 0). Eelistaksin ehk NA-ga klõpsamist ja argumenti "na.rm = TRUE" lisamist "tähendama". Vastus ei ole sama, mida OP soovis, kuid tundub kasulikum. Ma redigeerin oma vastust, et see sisalduks.
@ucfagls Seda on siiski lihtne muuta ja nagu te ütlesite, tegi selle eelduse OP. Teisalt oleksin veelgi piiravam ja eemaldaksin viimase keskmise.
Aitäh! Eriti sellepärast, et märkisin viimast väärtust nulloletuseks, ei olnud ma seda kaalunud. Kindlasti hoolin sellest viimasest aknast !!
#2
+14
r_evolutionist
2014-04-08 19:08:56 UTC
view on stackexchange narkive permalink

Rollapply töötab suurepäraselt väikese andmekogumiga. Kui aga töötate mitme miljoni reaga (genoomika), on see üsna aeglane.

Järgmine funktsioon on ülikiire.

  data <- c (runif (100000, min = 0, max = .1), runif (100000, min =. 05, max = .1), runif (10000, min = .05, max = 1), runif (100000, min = 0, max = .2)) slideFunct <- funktsioon (andmed, aken, samm) {kokku < - pikkus (andmed) laigud <- seq (alates = 1, kuni = (kogu-aken), by = samm) tulemus <- vektor (pikkus = pikkus (laigud)) jaoks (i ühes: pikkus (laigud)) { tulemus [i] <- keskmine (andmed [laigud [i] :( laigud [i] + aken)])} return (tulemus)}  

http: // coleoguy .blogspot.com / 2014/04 / sliding-window-analysis.html

Üsna kasulik.Kuid pidage meeles, et see aken = 3 tagastab 4 (!) Väärtuse keskmise, välja arvatud juhul, kui lisate vahemikusse -1 ja "+ 1".
Lihtsalt vihjena pole see funktsioon nii kiire, kui võite arvata: ma muutsin seda keskmise arvutamiseks mediaani arvutamiseks ja kasutasin seda 17 miljoni rea andmekogumi jaoks, mille akna suurus oli 3600 (samm = 1).Selle täitmine võttis aega 25 minutit.Lisaks kirjutasin samale ülesandele Go programmi ja see valmis 21 sekundi jooksul.Kuid probleem pole keeles, vaid algoritmis.Selle algoritmi jaoks on akna suurus kriitilise tähtsusega.Ma arvan, et TTR paketi valikud on palju paremad võimalused, kui otsite lihtsa liikuva keskmise arvutamist (vaadake teisi vastuseid).
#3
+5
user1414
2010-09-24 20:27:14 UTC
view on stackexchange narkive permalink

See lihtne koodirida teeb asja:

  ((c (x, 0,0) + c (0, x, 0) + c (0,0, x) ) / 3) [3: (pikkus (x) -1)]  

kui x on kõnealune vektor.

See ei anna tagasi seda, mida küsija soovis, vaid 5,33 5,00 6,33. See tundub aga üsna huvitav. Kas saaksite oma ideed selgitada, sest ma ei saa sellest aru.
@Henric Kasutan seda trikki sageli, kuid kasutaja1414 kood tagastab selle rulli slaidiga 1, mitte 2, nagu OP on ette näinud. Vaadake "(c (0,0, x) + c (0, x, 0) + c (x, 0,0)) / 3", et näha, mida ma mõtlen (ja kuidas see töötab). Õige valem oleks: "(c (0,0, x) + c (0, x, 0) + c (x, 0,0)) [1: (pikkus (x) -3) * 2 + 1 ] / 3` (peame alguses lõikama 0-polsterduse ja valima siis paariselemendid.
#4
+4
RockScience
2010-10-21 14:17:02 UTC
view on stackexchange narkive permalink
  teek (loomaaed) x = c (4, 5, 7, 3, 9, 8) rollmean (x, 3)  

või

  teek (TTR) x = c (4, 5, 7, 3, 9, 8) SMA (x, 3)  
Kas see töötab 2D-maatriksite puhul? Nagu kuidas? Kui akna suurus on näitena 3 * 3
see on ainult üks suund
#5
+3
shabbychef
2010-09-25 10:51:59 UTC
view on stackexchange narkive permalink

Ma saan seda teha Matlabis ja pardis hõlpsalt, kui te mind halvustate:

 % antud vektor x, windowsize, slide idx1 = 1: slide: numel (x); idx2 = min ( numel (x) + 1, idx1 + akna suurus); % sic kohta +1 siin ja ei -1; cx = [0; cumsum (x (:))]; % täidab nulli, teeb kumulatiivse summa; rv = (cx (idx2) - cx (idx1)) / aknasuurus; % tada! vastus!  

kõrvalnähuna on idx1 summa elemendi indeks. Olen kindel, et selle saab hõlpsasti tõlkida R-i. Idioom first: skip: last Matlabis annab massiivi first, first + skip, first + 2skip, ..., first + n skip, kus massiivi viimane element ei ole suurem kui last .

redigeeri : olin keskmistamise osa välja jätnud (jaga aknasuurusega ).

+1 Ei tada, rv / windowsize ;-)
See marg ... kommentaarikast on selle koodi jaoks liiga kitsas, nii et olen uue vastuse postitanud.
Aitäh, aga MATLAB pole tasuta !!
@T-Burns: oktaav on siiski tasuta; ka R on Matlabile piisavalt lähedal, et seda koodi oleks lihtne tõlkida. Tegelikult tegi @mbq seda ..
#6
+3
user88
2010-09-25 13:31:03 UTC
view on stackexchange narkive permalink

shabbychefi vastus R-s:

  slideMean<-function (x, windowsize = 3, slide = 2) {idx1<-seq (1, length (x) , by = slaid); idx1 + windowsize->idx2; idx2 [idx2> (pikkus (x) +1)] <-pikkus (x) +1; c (0, cumsum (x)) - >cx; return ((cx [idx2] -cx [idx1]) / windowsize);}  

MUUDA: otsitavad indeksid on lihtsalt idx1 ... seda funktsiooni saab hõlpsasti muuta ka nende tagastamiseks, kuid peaaegu sama kiiresti on neid uuesti luua uue kutsega seq (1, length (x), by = slide) .

aitäh tõlkimise eest. Arvasin, et see oleks lihtne harjutus, ja õppisin sellest R-i
Minu uuendatud vastus on kasutada minu [paketist] veritseva serva versiooni "from :: running_mean" (https://github.com/shabbychef/fromo/tree/dev)
#7
+1
Matt Parker
2010-09-24 21:40:33 UTC
view on stackexchange narkive permalink

See annab teile akna keskmised ja akna esimese väärtuse indeks:

  #The datax <- c (4, 5, 7, 3, 9, 8) #Määra akna suurus ja slidewin.size <- 3slide <- 2 # Tulemuste tabeli seadistamine <- data.frame (indeks = numbriline (), win.mean = numbriline ()) # i indekseerib akna esimese väärtuse (künnis?) i <- 1 # j indekseerib lisatavate tulemuste rea järgminej <- 1-ga (i <-pikkus (x)) {#See keskmine säilitab nimetaja 3 win.mean <- summa (x [ i: (i + 2)], na.rm = TÕENE) /win.size #Sisestage tulemuste tulemused [j,] <- c (i, win.mean) # Lisage järgmise passi indeksid i <- i + slide j <- j + 1}  

Kehtivad erinevad hoiatused: pole seda testinud millegi muu kui teie näidisandmetega; Usun, et sellistel andmeraamidel lisamine võib tõesti aeglustada, kui teil on palju väärtusi (kuna see kopeerib iga kord data.frame'i); jne. Kuid see toodab seda, mida te palusite.

Palun ärge hääletage alla kommentaari andmata. Kuidas ma peaksin teadma, mis viga on?
See ei olnud mina, kuid see on aeglane (kuid mitte palju aeglasem kui `rollapply`).
polnud ka mina, aga nagu te ise mainisite, aitab tulemuse objekti eeljaotus kiiruse probleemi lahendada. Üks nipp, kui te ei tea või on tüütu / raske kindlaks teha, millist tulemuse objekti vajate. Eraldage midagi mõistlikku, võib-olla eelnevalt NA-ga täita. Seejärel täitke oma silmus, kuid lisage kontroll, et kui lähenete eelnevalt paigutatud objekti piirile, eraldage veel üks suur osa ja jätkake täitmist.
@mbq; Kuigi tulemuste kiirus on oluline, pole see ainus kaalutlus. Selle asemel, et kohandatud lahendustes peaks aega uuesti leiutama ja kõiki indekse jms käsitsema, on ühe rulliga, mis on "rollapply", palju lihtsam mõista ja kavatsusest kinni haarata. Samuti on `rollapply`-l tõenäoliselt olnud palju rohkem silmamunade koodi kontrollimist kui midagi, mida ma võiksin ühel pärastlõunal küpsetada. Hobused kursustele.
ucfagls, aitäh, et lisasid teavet eeljaotuse kohta, kui te ei tea objekti lõplikku suurust - see on kasulik. Ja kuigi ma olen nõus, et rollapply on tõenäoliselt peaaegu kindlasti tee, tahtsin a) tuua näite, mis arvutaks vähem kui kolme väärtusega servajuhud ja b) tahtsin lihtsalt kasutada 'while ()', mida ma pole veel kasutamiseks;)
"[I: (i + 2)]" muutmine väärtuseks "[i: (i + win.size-1)]" muudaks koodi minu arvates üldisemaks.


See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 2.0-litsentsi eest, mille all seda levitatakse.
Loading...