What is the purpose of Data Sanitization?

Probe masking is important to prevent privacy data leakage. The goal of data sanitization is to modifiy IDAT files in place, so they can be released to public domain without privacy leak. This will be achieved by deIdentification. The following function requires the R package seSAMe.

Let’s take DNA methylation data from the HM450 platform for example.

dest_dir = tempdir()
res_grn = sesameDataDownload("3999492009_R01C01_Grn.idat", dest_dir=dest_dir)
res_red = sesameDataDownload("3999492009_R01C01_Red.idat", dest_dir=dest_dir)

deIdentify

Method 1

This first method of deIdentification masks SNP probe intensity mean by zero. As a consequence, the allele frequency will be 0.5.

deIdentify(res_grn$dest_file, sprintf("%s/deidentified_Grn.idat", dest_dir))
deIdentify(res_red$dest_file, sprintf("%s/deidentified_Red.idat", dest_dir))

betas1 = getBetas(readIDATpair(sprintf("%s/3999492009_R01C01", dest_dir)))
betas2 = getBetas(readIDATpair(sprintf("%s/deidentified", dest_dir)))

head(betas1[grep('rs',names(betas1))]) 
## rs10033147  rs1019916  rs1040870 rs10457834 rs10774834 rs10796216 
## 0.48831587 0.44527168 0.85344189 0.90835267 0.04676394 0.45331875
head(betas2[grep('rs',names(betas2))])
## rs10033147  rs1019916  rs1040870 rs10457834 rs10774834 rs10796216 
##        0.5        0.5        0.5        0.5        0.5        0.5

Note that before deIdentify, the rs values will all be different. After deIdentify, the rs values will all be masked at an intensity of 0.5.

Method 2

This second method of deIdentification will scramble the intensities using a secret key to help formalize a random number. Therefore, randomize needs to be set to TRUE.

my_secret <- 13412084
set.seed(my_secret)

deIdentify(res_grn$dest_file,
    sprintf("%s/deidentified_Grn.idat", dest_dir), randomize=TRUE)

my_secret <- 13412084
set.seed(my_secret)
deIdentify(res_red$dest_file,
    sprintf("%s/deidentified_Red.idat", dest_dir), randomize=TRUE)

betas1 = getBetas(readIDATpair(sprintf("%s/3999492009_R01C01", dest_dir)))
betas2 = getBetas(readIDATpair(sprintf("%s/deidentified", dest_dir)))

head(betas1[grep('rs',names(betas1))]) 
## rs10033147  rs1019916  rs1040870 rs10457834 rs10774834 rs10796216 
## 0.48831587 0.44527168 0.85344189 0.90835267 0.04676394 0.45331875
head(betas2[grep('rs',names(betas2))]) 
## rs10033147  rs1019916  rs1040870 rs10457834 rs10774834 rs10796216 
## 0.29653345 0.08937692 0.31610220 0.51297112 0.38290598 0.49381188

Note that the rs values are scrambled after deIdentify.

reIdentify

To restore order of the deIdentified intensities, one can re-identify IDATs. The reIdentify function can thus restore the scrambled SNP intensities.

my_secret <- 13412084
set.seed(my_secret)

reIdentify(sprintf("%s/deidentified_Grn.idat", dest_dir),
    sprintf("%s/reidentified_Grn.idat", dest_dir))

my_secret <- 13412084
set.seed(my_secret)
reIdentify(sprintf("%s/deidentified_Red.idat", dest_dir),
    sprintf("%s/reidentified_Red.idat", dest_dir))

betas1 = getBetas(readIDATpair(sprintf("%s/3999492009_R01C01", dest_dir)))
betas2 = getBetas(readIDATpair(sprintf("%s/reidentified", dest_dir)))

head(betas1[grep('rs',names(betas1))]) 
## rs10033147  rs1019916  rs1040870 rs10457834 rs10774834 rs10796216 
## 0.48831587 0.44527168 0.85344189 0.90835267 0.04676394 0.45331875
head(betas2[grep('rs',names(betas2))]) 
## rs10033147  rs1019916  rs1040870 rs10457834 rs10774834 rs10796216 
## 0.48831587 0.44527168 0.85344189 0.90835267 0.04676394 0.45331875

Note that reIdentify restored the values. Subsequently, they are the same as betas1.