Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
^\.RData$
^\.Ruserdata$
^\.Rproj\.user$
^\.github
^\.github
^CITATION\.cff$
33 changes: 33 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
cff-version: 1.2.0
message: "If you use methylTFR, please cite it as below."
type: software
title: "methylTFR: Quantification of DNA methylation signatures in TFBS"
abstract: >-
methylTFR is an R/Bioconductor package for analyzing DNA methylation
signatures within transcription factor binding sites (TFBS) in individual
cells or samples. It computes a GC-bias-corrected deviation score of
methylation levels at TF binding sites.
authors:
- family-names: Gunduz
given-names: Irem B.
email: irembgunduz@gmail.com
orcid: "https://orcid.org/0000-0003-2641-0916"
- family-names: Murugan
given-names: Sarath Kumar
orcid: "https://orcid.org/0000-0001-7378-7869"
- family-names: Mueller
given-names: Fabian
orcid: "https://orcid.org/0000-0001-5809-2321"
version: 0.99.8
date-released: "2026-08-19"
doi: 10.18129/B9.bioc.methylTFR
license: MIT
repository-code: "https://github.com/EpigenomeInformatics/methylTFR"
url: "https://epigenomeinformatics.github.io/methylTFR/"
keywords:
- R
- Bioconductor
- DNA methylation
- transcription factor binding sites
- single-cell
- epigenetics
10 changes: 7 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
Package: methylTFR
Title: Quantification of DNA Methylation Signatures in TFBS
Version: 0.99.7
Version: 0.99.8
Date: 2026-08-19
Authors@R: c(
person("Irem B.", "Gündüz", , "irembgunduz@gmail.com", role = c("aut", "cre"),
comment = c(ORCID = "0000-0003-2641-0916")),
person("Sarath Kumar", "Murugan", , "sarath.murugan@outlook.com", role = "aut",
comment = c(ORCID = "0000-0001-7378-7869")),
person("Fabian", "Muller", , "fabian.mueller@uni-saarland.de", role = "aut",
comment = c(ORCID = "0000-0001-5809-2321"))
person("Fabian", "Mueller", , "fabian.mueller@uni-saarland.de", role = "aut",
comment = c(ORCID = "0000-0001-5809-2321")),
person("ERA-NET Transcan-Neu III - EPILUNAR", role = "fnd",
comment = "Grant 01KT2409"),
person("Saarland University", role = "fnd",
comment = "NanoBioMed Young Investigator Grant")
)
Description: methylTFR is an extensive R package designed specifically for
analyzing DNA methylation signatures within transcription factor
Expand Down
24 changes: 24 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# methylTFR 0.99.8

BUG FIXES

* `read_methylome(type = "encode")` returned methylation scores that were not
fractions. `parse_encode()` divided column 11 by column 10, but in a bedMethyl
file column 10 is read coverage and column 11 is the percentage of reads
methylated, so a fully methylated CpG covered by five reads scored 20. The
score is now the percentage over 100.
* `parse_encode()` skipped the first line of every file unconditionally. Files
downloaded from ENCODE carry no header, so the first record was silently
discarded. The header is now detected.
* `read_methylome()` stops if the parsed scores fall outside 0 to 1 rather than
passing them to the deviation calculation.
* The `run_methylTFR_RnBeads()` example built an `RnBiseqSet` without setting
`identifiers.column`, so `samples()` returned row numbers and the example
stopped on the sample-identifier check. It now sets the option before
building the set and restores it afterwards.
* The bundled `encode.tsv.gz` example has been rebuilt. Columns 10 and 11 are
now named `coverage` and `percentMeth` rather than `blockCount` and
`blockSizes`, and the percentages span 0 to 100, so the tests exercise the
case the old example passed by luck.


# methylTFR 0.99.7

NEW FEATURES
Expand Down
36 changes: 32 additions & 4 deletions R/data_reader.R
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@ read_methylome <- function(filename, type, cov_threshold = 1) {

# Filter low coverage sites
gr_obj <- gr_obj[gr_obj$coverage >= cov_threshold]

# A methylation score is a fraction. Anything else means the file did not
# have the layout the requested type expects, and returning it silently
# would put nonsense into every deviation computed downstream.
if (length(gr_obj) > 0) {
rng <- range(gr_obj$score, na.rm = TRUE)
if (is.finite(rng[1]) && (rng[1] < 0 || rng[2] > 1)) {
stop(
"Methylation scores parsed from ", filename, " span ",
signif(rng[1], 3), " to ", signif(rng[2], 3),
", which is not a fraction. Check that '", type,
"' is the right format for this file."
)
}
}
return(gr_obj)
}

Expand Down Expand Up @@ -131,17 +146,30 @@ parse_bismarkcov <- function(filename) {

#' @keywords internal
parse_encode <- function(filename) {
# bedMethyl: column 10 is read coverage and column 11 is the percentage of
# reads methylated. Columns are taken by position, and the header is
# detected rather than assumed, because files downloaded from ENCODE carry
# no header line while the bundled example does.
msites <- data.table::fread(
filename,
header = FALSE, skip = 1, showProgress = FALSE
header = "auto", showProgress = FALSE
)
if (ncol(msites) < 11) {
logger::log_warn(sprintf("%s is an invalid encode file!", filename))
stop("encode file must contain 11 columns!")
}
mscore <- round(msites$V11 / msites$V10, 6)
cov <- msites$V10
msites <- msites[, .(V1, V2, V3, V6)]
cov <- as.numeric(msites[[10]])
pct <- as.numeric(msites[[11]])
if (any(pct > 100, na.rm = TRUE) || any(pct < 0, na.rm = TRUE)) {
stop(
"Column 11 of ", filename, " is outside 0-100, so it is not a ",
"methylation percentage. Check that this is a bedMethyl file."
)
}
mscore <- round(pct / 100, 6)
msites <- data.table::data.table(
V1 = msites[[1]], V2 = msites[[2]], V3 = msites[[3]], V6 = msites[[6]]
)
list(msites = msites, mscore = mscore, cov = cov)
}

Expand Down
65 changes: 51 additions & 14 deletions R/rnbeads_interface.R
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ resolve_rnb_sample_ann <- function(rnb_set, sample_ann, sample_ids) {
#'
#' if (requireNamespace("RnBeads", quietly = TRUE) &&
#' requireNamespace("RnBeads.hg38", quietly = TRUE)) {
#' # identifiers.column is a session option, not a property of the object,
#' # so it has to be set before the set is built or samples() falls back
#' # to row numbers and methylTFR cannot name the columns it returns
#' old_ids <- RnBeads::rnb.getOption("identifiers.column")
#' RnBeads::rnb.options(identifiers.column = "sampleName")
#'
#' sites <- data.frame(
#' chr = as.character(GenomicRanges::seqnames(msites)),
#' start = GenomicRanges::start(msites),
Expand All @@ -88,8 +94,10 @@ resolve_rnb_sample_ann <- function(rnb_set, sample_ann, sample_ids) {
#' rnb_set <- RnBeads::RnBiseqSet(
#' pheno = data.frame(sampleName = "sample_1"),
#' sites = sites,
#' meth = matrix(msites$score, ncol = 1),
#' covg = matrix(msites$coverage, ncol = 1),
#' meth = matrix(msites$score, ncol = 1,
#' dimnames = list(NULL, "sample_1")),
#' covg = matrix(msites$coverage, ncol = 1,
#' dimnames = list(NULL, "sample_1")),
#' assembly = "hg38",
#' summarize.regions = FALSE
#' )
Expand All @@ -100,6 +108,7 @@ resolve_rnb_sample_ann <- function(rnb_set, sample_ann, sample_ids) {
#' gcfreqs = gcfreqs,
#' gc_dist = gcdist
#' )
#' RnBeads::rnb.options(identifiers.column = old_ids)
#' deviations(devs)
#' }
#' @seealso \code{\link{run_methyltfr}} for running methylTFR from
Expand Down Expand Up @@ -149,29 +158,57 @@ run_methylTFR_RnBeads <- function(
#' @return A character vector of sample identifiers.
#' @keywords internal
rnb_sample_ids <- function(rnb_set) {
ids <- tryCatch(
colnames(RnBeads::meth(rnb_set, type = "sites", i = 1L)),
error = function(e) NULL
)
# Same as RnBeads' samples(): the column named by the
# "identifiers.column" option. samples() is not exported by all
# RnBeads versions, so it is not called directly.
ids <- tryCatch({
id_col <- RnBeads::rnb.getOption("identifiers.column")
ph <- RnBeads::pheno(rnb_set)
if (!is.null(id_col) && id_col %in% colnames(ph)) ph[[id_col]]
}, error = function(e) NULL)
if (length(ids) == 0) {
ids <- tryCatch(
rownames(RnBeads::pheno(rnb_set)),
colnames(RnBeads::meth(rnb_set, type = "sites", i = 1L)),
error = function(e) NULL
)
}
if (length(ids) == 0) {
nsamples <- tryCatch(
nrow(RnBeads::pheno(rnb_set)),
error = function(e) 0L
ids <- tryCatch(
rownames(RnBeads::pheno(rnb_set)),
error = function(e) NULL
)
if (length(nsamples) == 1 && nsamples > 0) {
ids <- paste0("sample_", seq_len(nsamples))
}
}
if (length(ids) == 0) {
stop("Could not determine sample identifiers from the RnBSet object.")
}
return(as.character(ids))
ids <- as.character(ids)
if (any(grepl("\\.idat$|_Grn|_Red", ids, ignore.case = TRUE))) {
stop(
"Sample identifiers look like IDAT channel files, not samples: '",
ids[1], "'. The RnBSet was imported with the raw channel files ",
"as samples, so each array appears twice and the methylation ",
"values are not comparable. Re-import with a sample sheet and ",
"an identifiers.column before running methylTFR."
)
}
if (identical(ids, as.character(seq_along(ids)))) {
stop(
"Sample identifiers are the row numbers 1..", length(ids),
", so the RnBSet carries no usable sample names in this ",
"session. identifiers.column is a session option rather than ",
"a property of the saved object, so set it before loading, ",
"for example rnb.options(identifiers.column = 'Sample.ID'), ",
"or assign colnames on the methylation matrix yourself."
)
}
if (anyDuplicated(ids)) {
stop(
"The RnBSet has duplicated sample identifiers, for example '",
ids[anyDuplicated(ids)], "'. Resolve or average the duplicates ",
"before running methylTFR."
)
}
return(ids)
}


Expand Down
20 changes: 15 additions & 5 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ library(methylTFRAnnotationHg38) # annotation package for hg38
library(methylTFR)

gcfreqs <- getGCfreq(motifSet = "jaspar2020")
gc_dist <- getGenomeGC("hg38")
gc_dist <- getGenomeGC()
tf_bindsites <- getTFbindsites(motifSet = "jaspar2020")

sample_dir <- file.path("samples_dir")
Expand All @@ -78,9 +78,19 @@ deviations <- run_methyltfr(sample_ann, # sample annotation file

## Citation

Below is the citation output from using `citation('methylTFR')` in R. Please
run this yourself to check for any updates on how to cite __methylTFR__.
If you use `methylTFR` in your work, please cite:

```{r 'citation', eval = requireNamespace('methylTFR')}
print(citation("methylTFR"), bibtex = TRUE)
> Gunduz IB, Murugan SK, Mueller F (2026). methylTFR: Quantification of DNA methylation signatures in TFBS. R package version 0.99.8. https://github.com/EpigenomeInformatics/methylTFR

```bibtex
@Manual{methylTFR,
title = {methylTFR: Quantification of DNA methylation signatures in TFBS},
author = {Irem B. Gunduz and Sarath Kumar Murugan and Fabian Mueller},
year = {2026},
note = {R package version 0.99.8},
url = {https://github.com/EpigenomeInformatics/methylTFR},
doi = {10.18129/B9.bioc.methylTFR},
}
```

Run `citation("methylTFR")` in R to get the entry for the version you have installed.
36 changes: 14 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ library(methylTFRAnnotationHg38) # annotation package for hg38
library(methylTFR)

gcfreqs <- getGCfreq(motifSet = "jaspar2020")
gc_dist <- getGenomeGC("hg38")
gc_dist <- getGenomeGC()
tf_bindsites <- getTFbindsites(motifSet = "jaspar2020")

sample_dir <- file.path("samples_dir")
Expand All @@ -73,27 +73,19 @@ deviations <- run_methyltfr(sample_ann, # sample annotation file

## Citation

Below is the citation output from using `citation('methylTFR')` in R. Please
run this yourself to check for any updates on how to cite __methylTFR__.
If you use `methylTFR` in your work, please cite:

> Gunduz IB, Murugan SK, Mueller F (2026). methylTFR: Quantification of DNA methylation signatures in TFBS. R package version 0.99.8. https://github.com/EpigenomeInformatics/methylTFR

```r
print(citation("methylTFR"), bibtex = TRUE)
#>
#> To cite package 'methylTFR' in publications use:
#>
#> Irem B. Gündüz, Sarath Kumar Murugan and Fabian Muller (2026).
#> methylTFR: Quantification of DNA Methylation Signatures in TFBS. R
#> package version 0.99.0.
#> https://github.com/EpigenomeInformatics/methylTFR
#>
#> A BibTeX entry for LaTeX users is
#>
#> @Manual{,
#> title = {methylTFR: Quantification of DNA Methylation Signatures in TFBS},
#> author = {Irem B. Gündüz and Sarath Kumar Murugan and Fabian Muller},
#> year = {2026},
#> note = {R package version 0.99.0},
#> url = {https://github.com/EpigenomeInformatics/methylTFR},
#> }
```bibtex
@Manual{methylTFR,
title = {methylTFR: Quantification of DNA methylation signatures in TFBS},
author = {Irem B. Gunduz and Sarath Kumar Murugan and Fabian Mueller},
year = {2026},
note = {R package version 0.99.8},
url = {https://github.com/EpigenomeInformatics/methylTFR},
doi = {10.18129/B9.bioc.methylTFR},
}
```

Run `citation("methylTFR")` in R to get the entry for the version you have installed.
47 changes: 30 additions & 17 deletions inst/CITATION
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
pkgVer <- function(pkg) {
if (!exists("meta") || is.null(meta)) meta <- packageDescription(pkg)
ver <- meta$Version
paste0('https://github.com/EpigenomeInformatics/methylTFR', ' - R package version ', ver)
if (!exists("meta") || is.null(meta)) {
meta <- packageDescription("methylTFR")
}

c(
bibentry(bibtype = "Manual",
title = "methylTFR: Quantification of DNA Methylation Signatures in TFBS",
author = personList(
as.person("Irem B. Gunduz"),
as.person("Sarath Kumar Murugan"),
as.person("Fabian Muller")
),
year = format(Sys.Date(), "%Y"),
url = "https://github.com/EpigenomeInformatics/methylTFR",
note = pkgVer('methylTFR'),
doi = "10.18129/B9.bioc.methylTFR"
pkg_year <- if (!is.null(meta$Date)) {
substr(meta$Date, 1, 4)
} else if (!is.null(meta$`Date/Publication`)) {
substr(meta$`Date/Publication`, 1, 4)
} else {
format(Sys.Date(), "%Y")
}
pkg_note <- sprintf("R package version %s", meta$Version)
pkg_title <- "methylTFR: Quantification of DNA methylation signatures in TFBS"
pkg_url <- "https://github.com/EpigenomeInformatics/methylTFR"

bibentry(
bibtype = "Manual",
header = "To cite methylTFR in publications use:",
title = pkg_title,
author = c(
person("Irem B.", "Gunduz"),
person("Sarath Kumar", "Murugan"),
person("Fabian", "Mueller")
),
year = pkg_year,
note = pkg_note,
url = pkg_url,
doi = "10.18129/B9.bioc.methylTFR",
textVersion = paste0(
"Gunduz IB, Murugan SK, Mueller F (", pkg_year, "). ",
pkg_title, ". ", pkg_note, ". ", pkg_url
)
)
)
Binary file modified inst/extdata/BATF_gcfreqs.rda
Binary file not shown.
Binary file modified inst/extdata/BATF_tf_bindsites.rda
Binary file not shown.
Binary file modified inst/extdata/encode.tsv.gz
Binary file not shown.
Binary file modified inst/extdata/example_data.rda
Binary file not shown.
Binary file modified inst/extdata/gcdist_BATF.rda
Binary file not shown.
Binary file modified inst/extdata/gcdist_subset.rda
Binary file not shown.
Binary file modified inst/extdata/msites_sub.rda
Binary file not shown.
Binary file modified inst/extdata/tc_mem.rda
Binary file not shown.
Binary file modified inst/extdata/tc_naive.rda
Binary file not shown.
Loading
Loading