From @jashapiro in #186 (comment):

I noticed in initial attempts to integrate CNV calls into #13 that there are a number of genes where CNVkit calls include both gain and loss for the vast majority of samples (see table below, noting that there are only 649 samples in the dataset used). This seems worth a bit of investigation. My initial guess is that most of these are bad calls in repetitive regions, and that restricting calls to exons may reduce this.

In #253 (current version of the branch here), we’ve moved to using exons.

Here, I’m looking at the instances where a gene (i.e., gene symbol) is called as both a gain and a loss within the same sample.

library(dplyr)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
# read in the output of `01-prepare-cn-file.R`
cnvkit_df <- readr::read_tsv(file.path("results", 
                                       "cnvkit_annotated_cn_autosomes.tsv.gz"))
Parsed with column specification:
cols(
  biospecimen_id = col_character(),
  status = col_character(),
  copy_number = col_double(),
  ploidy = col_double(),
  gene_symbol = col_character(),
  cytoband = col_character(),
  ensembl = col_character()
)
controlfreec_df <- readr::read_tsv(file.path("results",
                                             "controlfreec_annotated_cn_autosomes.tsv.gz"))
Parsed with column specification:
cols(
  biospecimen_id = col_character(),
  status = col_character(),
  copy_number = col_double(),
  ploidy = col_double(),
  gene_symbol = col_character(),
  cytoband = col_character(),
  ensembl = col_character()
)

CNVkit

cnvkit_events <- cnvkit_df %>%
  # for each specimen, see what events (e.g., gain, loss) happen for a 
  # particular gene (gene symbol)
  group_by(biospecimen_id, gene_symbol) %>%
  # this summarize step creates a column that will contain gain, loss if a 
  # gene gets called as both in the same sample
  summarize(status_events = paste(sort(unique(status)), collapse = ", ")) %>%
  # for each gene, count how many times a gene called as a gain, loss, 
  # amplification, or any combination
  group_by(gene_symbol, status_events) %>%
  tally()
# find instances where something is called both a gain and a loss
cnvkit_both_events <- cnvkit_events %>%
  filter(grepl("gain, loss", status_events)) %>%
  arrange(desc(n))

cnvkit_both_events

ControlFreeC

controlfreec_events <- controlfreec_df %>%
  # for each specimen, see what events (e.g., gain, loss) happen for a 
  # particular gene (gene symbol)
  group_by(biospecimen_id, gene_symbol) %>%
  # this summarize step creates a column that will contain gain, loss if a 
  # gene gets called as both in the same sample
  summarize(status_events = paste(sort(unique(status)), collapse = ", ")) %>%
  # for each gene, count how many times a gene called as a gain, loss, or both
  group_by(gene_symbol, status_events) %>%
  tally()
# find instances where something is called both a gain and a loss
controlfreec_both_events <- controlfreec_events %>%
  filter(grepl("gain, loss", status_events)) %>%
  arrange(desc(n))

controlfreec_both_events

This seems to be a much bigger problem in CNVkit.

intersect(cnvkit_both_events$gene_symbol, controlfreec_both_events$gene_symbol)
  [1] "CCDC144B"            "LOC112268389"        "LOC729732"          
  [4] "CNTNAP3B"            "USP17L10"            "MUC4"               
  [7] "FAM182A"             "LOC101928626"        "DUX4"               
 [10] "LOC100996442"        "SPDYE16"             "DMBT1"              
 [13] "EPN2"                "POTEB3"              "TEKT4P2"            
 [16] "KIR3DL1"             "NUTM2B-AS1"          "ZAN"                
 [19] "ZNF595"              "ANKRD36B"            "FAM86B3P"           
 [22] "ZDHHC11B"            "ADAM5"               "GUSBP1"             
 [25] "HEATR4"              "PDPR"                "LOC101929823"       
 [28] "NPEPPSP1"            "SOX6"                "CES1P1"             
 [31] "KIR2DL1"             "NUTM2B"              "PDZD2"              
 [34] "PTEN"                "TRAPPC9"             "ADAMTSL1"           
 [37] "ATF7IP"              "BET1L"               "BTNL3"              
 [40] "BTNL8"               "CENPBD1P1"           "CLSTN2"             
 [43] "HSF2BP"              "KCNMA1"              "KRTAP9-6"           
 [46] "MFSD14C"             "PCDHA8"              "RCAN2"              
 [49] "RPS9"                "TRAPPC10"            "TRG-AS1"            
 [52] "AMPD3"               "AOPEP"               "ASAP1"              
 [55] "ASCC1"               "ATAD3B"              "BCKDK"              
 [58] "CAPZA2"              "CCDC171"             "COMMD10"            
 [61] "CPN1"                "DGKB"                "DLEU1"              
 [64] "DLG2"                "DOCK1"               "DOCK3"              
 [67] "DSCAM"               "FAM66E"              "FCRL3"              
 [70] "FUT11"               "GRID1"               "GRM5"               
 [73] "HELLS"               "HIF1AN"              "KIR2DL3"            
 [76] "LILRA6"              "LILRB3"              "LINC00958"          
 [79] "LINC01193"           "LINC01572"           "LINC02653"          
 [82] "LOC100653233"        "LOC101927533"        "LOC101929141"       
 [85] "LRRC4C"              "MARCHF3"             "MGAT4C"             
 [88] "MGMT"                "MLIP"                "MRGPRG-AS1"         
 [91] "NEBL"                "OR52N1"              "OSBPL5"             
 [94] "PCDH15"              "PCGF6"               "PDGFC"              
 [97] "PPIF"                "PSG9"                "PSMA1"              
[100] "PTCH1"               "PTPRJ"               "RBPMS"              
[103] "RICTOR"              "RP1"                 "RPL23AP87"          
[106] "RSRP1"               "RXFP1"               "SOX2-OT"            
[109] "SYNE2"               "TPTEP1"              "TSPAN18"            
[112] "TTC28"               "AASDHPPT"            "AEBP2"              
[115] "AFAP1"               "AGAP3"               "AIFM2"              
[118] "AMPH"                "ANK1"                "ANK3"               
[121] "ANKRD28"             "ANKRD36"             "ANO3"               
[124] "ATM"                 "ATP6V1C1"            "AVEN"               
[127] "BAZ2B"               "C11orf49"            "C22orf39"           
[130] "C3orf67"             "CACNA1C"             "CBARP"              
[133] "CCDC26"              "CCDC60"              "CCT8"               
[136] "CD96"                "CDH18"               "CDKN2B-AS1"         
[139] "CDYL2"               "CELF1"               "CEP128"             
[142] "CGNL1"               "CHAF1A"              "CHD2"               
[145] "CHL1"                "CHL1-AS1"            "CHRM5"              
[148] "CHURC1-FNTB"         "CIC"                 "CNTLN"              
[151] "CNTNAP2"             "COL20A1"             "COL22A1"            
[154] "COLQ"                "COX6C"               "CTBP2"              
[157] "CUX1"                "DACT3"               "DBET"               
[160] "DENND1C"             "DENND3"              "DIO2"               
[163] "DLEU2"               "DLG1"                "DOCK4"              
[166] "DOK3"                "DUSP4"               "EEF1AKMT2"          
[169] "EGR3"                "EIF2B1"              "EIF4EBP2"           
[172] "EPB41L3"             "ERC2"                "ERCC1"              
[175] "EXD3"                "FAM230G"             "FAM3D"              
[178] "FBXL14"              "FCHSD2"              "FGF14"              
[181] "FGF7P6"              "FGFR2"               "FLJ31356"           
[184] "FNTB"                "FOSL2"               "FOXN3"              
[187] "FUT5"                "GAB2"                "GANC"               
[190] "GATD3B"              "GGTLC3"              "GLO1"               
[193] "GNG2"                "GRAP"                "GRIK4"              
[196] "GRM4"                "GRM7"                "GTF2A1"             
[199] "GYPA"                "GZF1"                "HABP2"              
[202] "HDAC9"               "HGD"                 "HIRA"               
[205] "HLCS"                "HSCB"                "IP6K1"              
[208] "IQSEC3"              "IRS2"                "KALRN"              
[211] "KCND2"               "KHSRP"               "KIR2DS4"            
[214] "KIRREL3"             "LARGE1"              "LETM2"              
[217] "LHPP"                "LINC00506"           "LINC01435"          
[220] "LINC02055"           "LMO4"                "LOC100507642"       
[223] "LOC101927708"        "LOC101928978"        "LOC105370027"       
[226] "LOC339192"           "LRBA"                "LRP1B"              
[229] "LRP5L"               "LRRC6"               "LURAP1L"            
[232] "LY96"                "MACROH2A2"           "MAP3K7CL"           
[235] "MARCHF1"             "MAX"                 "MKRN2"              
[238] "MPPED2-AS1"          "MSI2"                "MTA1"               
[241] "MYO10"               "MYO1H"               "MYT1L"              
[244] "MYT1L-AS1"           "NAA15"               "NAGLU"              
[247] "NAV2"                "NCOA1"               "NCOR2"              
[250] "NEGR1"               "NFIA"                "NOVA2"              
[253] "NR4A2"               "NRAP"                "NSD3"               
[256] "NTRK2"               "NUTM1"               "OBI1-AS1"           
[259] "OC90"                "OR2T29"              "P4HA1"              
[262] "PALD1"               "PAOX"                "PCLO"               
[265] "PCMTD2"              "PELI2"               "PITPNC1"            
[268] "PKD1P5-LOC105376752" "PKM"                 "PLCB1"              
[271] "PLEKHA7"             "POTEB"               "PPM1H"              
[274] "PRKDC"               "PRMT3"               "PROB1"              
[277] "PRPSAP2"             "PRTFDC1"             "PSG4"               
[280] "PTMA"                "PTPRM"               "PVT1"               
[283] "PXDNL"               "PXK"                 "RALGAPA2"           
[286] "RARB"                "RBM6"                "RFX3-AS1"           
[289] "RNF165"              "RSPH14"              "RXYLT1"             
[292] "SAFB"                "SAFB2"               "SCHIP1"             
[295] "SDE2"                "SEMA6D"              "SHANK2"             
[298] "SHANK3"              "SHC4"                "SIN3A"              
[301] "SLC12A6"             "SLC37A1"             "SLC7A1"             
[304] "SMAD7"               "SNRPN"               "SPIDR"              
[307] "SPRED1"              "SPRN"                "SPRY2"              
[310] "SRGAP1"              "SRRM4"               "STK24"              
[313] "STK3"                "STXBP4"              "STXBP5L"            
[316] "SYN3"                "TADA2A"              "TAFA5"              
[319] "TANC1"               "TAOK3"               "TDRD3"              
[322] "TEKT3"               "TEX26-AS1"           "TMEM239"            
[325] "TMEM64"              "TMEM87A"             "TMTC3"              
[328] "TOM1L1"              "TPD52"               "TRAF3"              
[331] "TRIM41"              "TRIM48"              "TSC2"               
[334] "TSHZ1"               "TSNARE1"             "TSPAN15"            
[337] "TSPAN9"              "TSTA3"               "UBE2R2"             
[340] "USP47"               "VAV1"                "WWC1"               
[343] "ZADH2"               "ZBTB20"              "ZBTB7A"             
[346] "ZC3H3"               "ZCCHC2"              "ZFAT"               
[349] "ZFHX3"               "ZMIZ1"               "ZNF365"             
[352] "ZNF451"              "ZNF529"              "ZNF536"             
[355] "ZNF677"              "ZNF718"              "ZNF77"              
[358] "ZNF880"             
LS0tCnRpdGxlOiAiRm9yIENOViBtZXRob2RzLCBob3cgbWFueSBpbnN0YW5jZXMgb2YgYSBnZW5lIGJlaW5nIG1hcmtlZCBhcyBhIGdhaW4gYW5kIGEgbG9zcyBkbyB3ZSBoYXZlPyIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogSi4gVGFyb25pIGZvciBBTFNGIENDREwKZGF0ZTogMjAxOQotLS0KCkZyb20gQGphc2hhcGlybyBpbiBbIzE4NiAoY29tbWVudCldKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzL2lzc3Vlcy8xODYjaXNzdWVjb21tZW50LTU1MDM5MTI5Nyk6Cgo+IEkgbm90aWNlZCBpbiBpbml0aWFsIGF0dGVtcHRzIHRvIGludGVncmF0ZSBDTlYgY2FsbHMgaW50byBbIzEzXShodHRwczovL2dpdGh1Yi5jb20vQWxleHNMZW1vbmFkZS9PcGVuUEJUQS1hbmFseXNpcy9pc3N1ZXMvMTMpIHRoYXQgdGhlcmUgYXJlIGEgbnVtYmVyIG9mIGdlbmVzIHdoZXJlIENOVmtpdCBjYWxscyBpbmNsdWRlIGJvdGggZ2FpbiBhbmQgbG9zcyBmb3IgdGhlIHZhc3QgbWFqb3JpdHkgb2Ygc2FtcGxlcyAoc2VlIHRhYmxlIGJlbG93LCBub3RpbmcgdGhhdCB0aGVyZSBhcmUgb25seSA2NDkgc2FtcGxlcyBpbiB0aGUgZGF0YXNldCB1c2VkKS4gVGhpcyBzZWVtcyB3b3J0aCBhIGJpdCBvZiBpbnZlc3RpZ2F0aW9uLiBNeSBpbml0aWFsIGd1ZXNzIGlzIHRoYXQgbW9zdCBvZiB0aGVzZSBhcmUgYmFkIGNhbGxzIGluIHJlcGV0aXRpdmUgcmVnaW9ucywgYW5kIHRoYXQgcmVzdHJpY3RpbmcgY2FsbHMgdG8gZXhvbnMgbWF5IHJlZHVjZSB0aGlzLgoKSW4gWyMyNTNdKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzL3B1bGwvMjUzKSAoY3VycmVudCB2ZXJzaW9uIG9mIHRoZSBicmFuY2ggW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9qYWNseW4tdGFyb25pL09wZW5QQlRBLWFuYWx5c2lzL3RyZWUvYTVmOGE2YmUxM2RiMjRiM2Y0NWVkN2U1ZjZkNGI4NzM2ZTExZWQ2MS9hbmFseXNlcy9mb2NhbC1jbi1maWxlLXByZXBhcmF0aW9uKSksIHdlJ3ZlIG1vdmVkIHRvIHVzaW5nIGV4b25zLgoKSGVyZSwgSSdtIGxvb2tpbmcgYXQgdGhlIGluc3RhbmNlcyB3aGVyZSBhIGdlbmUgKGkuZS4sIGdlbmUgc3ltYm9sKSBpcyBjYWxsZWQgYXMgYm90aCBhIGdhaW4gYW5kIGEgbG9zcyB3aXRoaW4gdGhlIHNhbWUgc2FtcGxlLgoKYGBge3J9CmxpYnJhcnkoZHBseXIpCmBgYAoKYGBge3J9CiMgcmVhZCBpbiB0aGUgb3V0cHV0IG9mIGAwMS1wcmVwYXJlLWNuLWZpbGUuUmAKY252a2l0X2RmIDwtIHJlYWRyOjpyZWFkX3RzdihmaWxlLnBhdGgoInJlc3VsdHMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNudmtpdF9hbm5vdGF0ZWRfY25fYXV0b3NvbWVzLnRzdi5neiIpKQpjb250cm9sZnJlZWNfZGYgPC0gcmVhZHI6OnJlYWRfdHN2KGZpbGUucGF0aCgicmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb250cm9sZnJlZWNfYW5ub3RhdGVkX2NuX2F1dG9zb21lcy50c3YuZ3oiKSkKYGBgCgojIyMgQ05Wa2l0CgpgYGB7cn0KY252a2l0X2V2ZW50cyA8LSBjbnZraXRfZGYgJT4lCiAgIyBmb3IgZWFjaCBzcGVjaW1lbiwgc2VlIHdoYXQgZXZlbnRzIChlLmcuLCBnYWluLCBsb3NzKSBoYXBwZW4gZm9yIGEgCiAgIyBwYXJ0aWN1bGFyIGdlbmUgKGdlbmUgc3ltYm9sKQogIGdyb3VwX2J5KGJpb3NwZWNpbWVuX2lkLCBnZW5lX3N5bWJvbCkgJT4lCiAgIyB0aGlzIHN1bW1hcml6ZSBzdGVwIGNyZWF0ZXMgYSBjb2x1bW4gdGhhdCB3aWxsIGNvbnRhaW4gZ2FpbiwgbG9zcyBpZiBhIAogICMgZ2VuZSBnZXRzIGNhbGxlZCBhcyBib3RoIGluIHRoZSBzYW1lIHNhbXBsZQogIHN1bW1hcml6ZShzdGF0dXNfZXZlbnRzID0gcGFzdGUoc29ydCh1bmlxdWUoc3RhdHVzKSksIGNvbGxhcHNlID0gIiwgIikpICU+JQogICMgZm9yIGVhY2ggZ2VuZSwgY291bnQgaG93IG1hbnkgdGltZXMgYSBnZW5lIGNhbGxlZCBhcyBhIGdhaW4sIGxvc3MsIAogICMgYW1wbGlmaWNhdGlvbiwgb3IgYW55IGNvbWJpbmF0aW9uCiAgZ3JvdXBfYnkoZ2VuZV9zeW1ib2wsIHN0YXR1c19ldmVudHMpICU+JQogIHRhbGx5KCkKYGBgCgpgYGB7cn0KIyBmaW5kIGluc3RhbmNlcyB3aGVyZSBzb21ldGhpbmcgaXMgY2FsbGVkIGJvdGggYSBnYWluIGFuZCBhIGxvc3MKY252a2l0X2JvdGhfZXZlbnRzIDwtIGNudmtpdF9ldmVudHMgJT4lCiAgZmlsdGVyKGdyZXBsKCJnYWluLCBsb3NzIiwgc3RhdHVzX2V2ZW50cykpICU+JQogIGFycmFuZ2UoZGVzYyhuKSkKCmNudmtpdF9ib3RoX2V2ZW50cwpgYGAKCiMjIyBDb250cm9sRnJlZUMKCmBgYHtyfQpjb250cm9sZnJlZWNfZXZlbnRzIDwtIGNvbnRyb2xmcmVlY19kZiAlPiUKICAjIGZvciBlYWNoIHNwZWNpbWVuLCBzZWUgd2hhdCBldmVudHMgKGUuZy4sIGdhaW4sIGxvc3MpIGhhcHBlbiBmb3IgYSAKICAjIHBhcnRpY3VsYXIgZ2VuZSAoZ2VuZSBzeW1ib2wpCiAgZ3JvdXBfYnkoYmlvc3BlY2ltZW5faWQsIGdlbmVfc3ltYm9sKSAlPiUKICAjIHRoaXMgc3VtbWFyaXplIHN0ZXAgY3JlYXRlcyBhIGNvbHVtbiB0aGF0IHdpbGwgY29udGFpbiBnYWluLCBsb3NzIGlmIGEgCiAgIyBnZW5lIGdldHMgY2FsbGVkIGFzIGJvdGggaW4gdGhlIHNhbWUgc2FtcGxlCiAgc3VtbWFyaXplKHN0YXR1c19ldmVudHMgPSBwYXN0ZShzb3J0KHVuaXF1ZShzdGF0dXMpKSwgY29sbGFwc2UgPSAiLCAiKSkgJT4lCiAgIyBmb3IgZWFjaCBnZW5lLCBjb3VudCBob3cgbWFueSB0aW1lcyBhIGdlbmUgY2FsbGVkIGFzIGEgZ2FpbiwgbG9zcywgb3IgYm90aAogIGdyb3VwX2J5KGdlbmVfc3ltYm9sLCBzdGF0dXNfZXZlbnRzKSAlPiUKICB0YWxseSgpCmBgYAoKYGBge3J9CiMgZmluZCBpbnN0YW5jZXMgd2hlcmUgc29tZXRoaW5nIGlzIGNhbGxlZCBib3RoIGEgZ2FpbiBhbmQgYSBsb3NzCmNvbnRyb2xmcmVlY19ib3RoX2V2ZW50cyA8LSBjb250cm9sZnJlZWNfZXZlbnRzICU+JQogIGZpbHRlcihncmVwbCgiZ2FpbiwgbG9zcyIsIHN0YXR1c19ldmVudHMpKSAlPiUKICBhcnJhbmdlKGRlc2MobikpCgpjb250cm9sZnJlZWNfYm90aF9ldmVudHMKYGBgCgoqKlRoaXMgc2VlbXMgdG8gYmUgYSBtdWNoIGJpZ2dlciBwcm9ibGVtIGluIENOVmtpdC4qKgoKYGBge3J9CmludGVyc2VjdChjbnZraXRfYm90aF9ldmVudHMkZ2VuZV9zeW1ib2wsIGNvbnRyb2xmcmVlY19ib3RoX2V2ZW50cyRnZW5lX3N5bWJvbCkKYGBgCgo=