UMCUneuro / MRI

Research done extraordinarily easy. Wisdom of the crowd. Share your own script. :-)
GNU General Public License v3.0
0 stars 4 forks source link

Check dates #4

Closed HJWesteneng closed 6 years ago

HJWesteneng commented 6 years ago

Maak format om datums te controleren. Zie voor een eerste opzet sheet2 van Format_v1.xlsx.

HJWesteneng commented 6 years ago

Check dates:

  1. matrix in Sheet2 van Format_v1.xlsx gemaakt.
  2. matrix wordt in script omgezet in pairwise dependencies.
  3. indien er een discrepantie is tussen opgegeven dependency en werkelijke data (bijv. DoB na DoO, dan worden alle "downstream" gerelateerde datums op NA gezet, incl. de datum zelf).

Uitleg over "downstream": Als er bijv. 3 datums zijn: DoO, DoDiag en DoDeath en er wordt een fout gevonden in de pair DoO - DoDiag, dan worden DoO, DoDiag en ook DoDeath allemaal op NA gezet. Dit doe ik omdat je van de pair DoO - DoDiag niet weet welke er niet klopt (en dit ook moeilijk te weten kunt komen zonder de brondata te controleren) en daardoor weet je ook niet meer of de pair DoDiag - DoDeath klopt en zet ik dus ook DoDeath op NA (als de pair DoO - doDiag niet klopt). Dit is vrij streng maar misschien wel het veiligste.

Als de pair DoDiag - DoDeath niet klopt zet ik DoDiag en DoDeath op NA, maar DoO zet ik niet op NA. Je zou met een vergelijkbare redering als hierboven kunnen zeggen dat dit ook zou moeten. Echter is het zo dat "upstream" datums (zoals DoB of DoO) vaak met relatief veel andere variabelen connected zijn. Als die pairs allemaal kloppen is het onlogisch om DoB of DoO ook op NA te zetten en als die andere pairs niet kloppen wordt DoB automatisch al op NA gezet (en speelt het hele probleem niet meer).

Er zijn nog verfijndere manieren mogelijk waarmee je van alle omringende data gebruik zou kunnen maken en zo alles tegen elkaar af kunt wegen en dan een beste educated guess kunt doen, maar ook dit wordt waarschijnlijk nooit 100% waterdicht. De bottomline is denk ik dat als je een discrepantie vindt, dat je dan terug moet naar de brondata (N is nu rond de 32 van rond de 16000).

@HHGTan ik ben benieuwd wat je van het bovenstaande vindt.

HJWesteneng commented 6 years ago

Soms is er een probleem met longitudinale data. Als er bijv. bij iemand longitudinaal 5x een ALSFRS-R afgenomen is, waarvan (volgens Progeny) 2x voor diagnose, dan wordt momenteel o.a. het veld DoDiag 2x op NA gezet (en 3x niet). Hierdoor is de cross-sectionele data niet meer uniek (i.e. heeft >1 rij nodig om alle variatie weer te geven, terwijl dat voor cross-sectionele data logisch gezien onmogelijk zou moeten zijn). Hoe hier mee om te gaan?

HHGTan commented 6 years ago

Na cartesian merges, uniques en splits lijken de datasets niet meer geheel van gelijke grootte te zijn. (Zie: lapply(long3, dim) en lapply(long4,dim) ). Het kan zo zijn dat data verloren gaat in deze herstructurering, bv: Iemand die 2x dezelfde FVC score haalt, maar 1x keer op een ontbrekende datum en 1x op een foutieve datum, zou er uit vallen na onze data cleaning. Ik denk dat het beter is om deze datums direct in long3 op NA te zetten, aan de hand van de checks die in merge1 plaatsvinden.

Plan:

  1. Datums controleren in het merge1 dataframe (wide format met per ALSnr, alle combinaties van mogelijke datums).
  2. De foutieve datums doorgeven zodat deze in de list met longitudinale data long3 op NA worden gezet.
HJWesteneng commented 6 years ago

@HHGTan het probleem met lapply(long3, dim) en lapply(long4, dim) is makkelijk op te lossen door aan de longitudinale variabelen een kolom ProgenyFU_<var> toe te voegen. Iedere longitudinale rij is daarmee uniek (icm ALSnr) en kan dus niet verwijderd worden. Dit maakt van origine longitudinale data ook meer uniform met de wide2long longitudinale data. Als ik jouw voorstel goed begrijp dan zal het denk ik erg complex zijn om "downstream" datums op NA te zetten. Voor de volledigheid heb ik nog een check in het script ingebouwd dat lapply(long3, dim) en lapply(long4, dim) identiek moeten zijn.

Het bovenstaande (dus met ProgenyFU_<var>) biedt nog geen oplossing voor problemen met longitudinale variabelen, zoals in mijn vorige comment beschreven. Daarom besloten om bij discrepanties met longitudinale data alleen de datum van het longitudinale veld op NA te zetten.

Aan het eind check ingebouwd of pre- en postprocessing cross & long data voldoende overeenkomen (i.e. geen subjecten verwijderd of gedupliceerd e.d.).

Bovenstaande wijzigingen doorgevoerd met commit. Ik ben benieuwd wat je van deze oplossingen vindt.

HJWesteneng commented 6 years ago

Een ander alternatief voor longitudinale data zou kunnen zijn om het zo te doen als voorheen en initieel te accepteren dat het dan voor kan komen dat een uniek individu in de cross-sectionele data >1 rij krijgt (dus eigenlijk een soort duplicate). Vervolgens kun je dan een regeltje script maken dat als je iets dergelijks tegenkomt, dat je dan altijd voorkeur hebt voor de rij met de meeste missings (of beter, iedere kolom missing maakt waar >0 missings in voorkomen). Deze methodologie spreekt me eigenlijk ook wel erg aan omdat het qua opzet identiek is aan hoe er om gegaan wordt met discrepanties van datums in cross-sectionele data. @HHGTan wat vind jij?

HHGTan commented 6 years ago

Oh sorry @HJWesteneng , ik had in de branch datesbyHarold al een script gemaakt waarin de variabelen in long 3 op NA worden gezet, wel aan de hand van tests in merge1. Moet deze nog annoteren.

HHGTan commented 6 years ago

Ik denk momenteel nog even na over je suggesties... :)

HJWesteneng commented 6 years ago

@HHGTan OK. Super! Test het vooral ook even, ik denk dat het redelijk hufter proof is :-). En door ProgenyFU_<var> standaard te implementeren wordt longitudinale data ook uniformer. Ik ben benieuwd wat je er van vindt.

Ik denk dat jouw approach heel mooi is om toe te voegen aan meldingen file (mm). Het geeft een mooi overzicht wat dan op H2 waarschijnlijk makkelijke verwerkt kan worden. Is dat een idee?

HJWesteneng commented 6 years ago

En als je "jouw" methode inderdaad gebruikt voor mm zou je kunnen overwegen om alleen de discrepante kolommen weer te geven in out1 (dus niet alle "downstream" kolommen). Ik vind dat overzicht (out1) erg mooi.

HHGTan commented 6 years ago

Edit: @HJWesteneng Excuus, ik zie nu dat ik hem nog niet gecommit had. Werd tijdens het scripten weggebeld haha. Werp svp nog een blik op mijn branch :) hieronder wat toelichting.

Ik denk dat jouw approach heel mooi is om toe te voegen aan meldingen file (mm). Het geeft een mooi overzicht wat dan op H2 waarschijnlijk makkelijke verwerkt kan worden. Is dat een idee?

Klopt, je moet mijn script eigenlijk alleen runnen to line 572. Ik was nog niet eraan toegekomen om de rest te verwerken. Maar hij maakt al meldingen in mm. Daarbij geeft hij inderdaad een overzicht van alle waardes die veranderd zijn, niet zozeer de discrepante kolommen. Dit kan natuurlijk aangepast worden.

Ik moet jouw code nog testen, maar ik twijfel of het niet iets te complex wordt zo. Omdat we de data wrangling, i.e. (d3 + long3) --> merge1 --> (d4 + long 4), wel erin blijven houden en dit het misschien onnodig moeilijk maakt.

Mijn opzet is denk ik iets simpeler, omdat we vanuit merge1 een overzicht maken van alle Do<var> die veranderd moeten worden, en deze passen we per kolom (dus per Do<var>) in de bijbehorende data.table(long3 en d3) aan. Ik heb nog geen flaws in deze redering bedacht, maar ik hoor graag wat je ervan vindt.

Morgen zal ik nog even een betere blik op je script werpen en kijken hoe de ins en outs hiervan zijn:)

HJWesteneng commented 6 years ago

@HHGTan OK. Ik heb even naar de datesbyHarold branch gekeken. Voor de discussie hieronder even de stappen:

datesbyHarold branch

master branch

Samenvatting: voornamelijk de laatste stap is anders. In datesbyHarold is het gevaar dat er in d3 iets op NA gezet wordt wat niet op NA gezet had moeten worden (is nu nog niet af gescript), gevaar in master is dat de split van merge1 in d4 en long4 duplicates oplevert of er subjecten verwijderd worden die niet verwijderd hadden moeten worden (is ip wel afgescript, ik zou nog wel mijn voorstel voor changes in longitudinale data door willen voeren, wordt het eenvoudiger van, zolang ALSnr en ProgenyFU_<var> uniek zijn kan er niets fout gaan). Ik denk dat de verschillen klein zijn en de complexiteit (zeker na doorvoeren van mijn voorstel voor omgaan met longitudinale data) vergelijkbaar is. Ik ben benieuwd wat jij er van vindt en of ik hierboven nog iets over het hoofd zie.

HJWesteneng commented 6 years ago

@HHGTan In de branch long_dates heb ik jouw (met messages) en mijn ideeën (met combine - apply - split) samengevoegd. Ook eenvoudiger handling van longitudinale dates. Zie bijv commit: https://github.com/UMCUneuro/MRI/commit/c6e750a1c9e939c011944b85eaf92c587a56f093. Wat vind je hier van?

HHGTan commented 6 years ago

Ha @HJWesteneng , mooi werk hoor. Het script lijkt alles in principe goed te doen. Conceptueel blijft de gedachte echter bij mij wringen, omdat we toch die combines/uniques/splits blijven toepassen en het naar mijn mening dus enigszins onoverzichtelijk/risicovol wordt, ook al worden deze risico's dus wel ondervangen.

In datesbyHarold is het gevaar dat er in d3 iets op NA gezet wordt wat niet op NA gezet had moeten worden (is nu nog niet af gescript)

Bij mijn manier zie ik deze risico's eigenlijk niet, omdat er altijd op de combinatie ALSnr & Do<var> wordt geselecteerd en dit per definitie goed gaat. Desnoods zouden de NA veranderingen ook toegepast kunnen worden nadat d4 <- copy(d3) wordt gedaan. Zo kan je nog makkelijker verschillen tussen voor (d3) en na (d4) NA omzettingen zien.

Ik denk dus dat je mijn methode beter kan illusteren als: d3&long3 - combine (en test) \ apply + apply --> d4&long4

Kortom: Je script doet het uitstekend en de risico's worden ondervangen, maar ik denk dat we deze risico's helemaal niet hoeven te nemen. Ik hoor graag je mening:)

HJWesteneng commented 6 years ago

Ha @HHGTan Ik heb nog even onze beide script uitgebreid naast elkaar gelegd. Uiteindelijk kom ik tot de volgende conclusie:

Vind je het OK als ik een pull request maak van de dates_long branch?

HHGTan commented 6 years ago

Ja hij doet het gewoon goed, dus je kan m mergen :)

HJWesteneng commented 6 years ago

OK. Gemerged.