Skip to content

Commit

Permalink
Merge pull request #4 from DIDSR/master
Browse files Browse the repository at this point in the history
Update my fork
  • Loading branch information
SiWen314 authored Nov 11, 2020
2 parents 28b60b7 + df85cde commit 339352d
Show file tree
Hide file tree
Showing 140 changed files with 397 additions and 162 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@
/Rpackage/iMRMC.Rcheck
/Rpackage/iMRMC_1.2.1.tar.gz
/Rpackage/iMRMC/man
/Rpackage/iMRMC/input.imrmc
/Rpackage/iMRMC/tests/testthat/Rplots.pdf
/iMRMC.Rproj
/Rpackage/iMRMC_1.2.2.tar.gz
/Rpackage/iMRMC_1.2.2.zip
/Rpackage/iMRMC_1.2.3.tar.gz
/Rpackage/iMRMC_1.2.3.zip
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h3>README for iMRMC and iRoeMetz</h3>

Visit the <a href="https://github.com/DIDSR/iMRMC/releases" rel="nofollow">release Page</a> to download the programs.
Visit the <a href="https://github.com/DIDSR/iMRMC/releases" rel="nofollow">release Page</a> to download the software or access the repository [HERE](https://github.com/DIDSR/iMRMC).

The documentation for both packages can be found <a href="http://didsr.github.io/iMRMC/" rel="nofollow">here.</a>

Expand All @@ -15,6 +15,11 @@ Desc: The primary objective of the iMRMC application is to assist investigators
* The core iMRMC application is a stand-alone, precompiled, license-free Java applications and the source code. It can be used in GUI mode or on the command line.
* There is also an R package that utilizes the core Java application. Examples for using the programs can be found in the R help files.

Here are some ways to cite our work:
* Gallas, Brandon D., Andriy Bandos, Frank Samuelson, and Robert F. Wagner. “A Framework for Random-Effects ROC Analysis: Biases with the Bootstrap and Other Variance Estimators.” Commun Stat A-Theory 38, no. 15 (2009): 2586–2603. https://doi.org/10.1080/03610920802610084.
* Gallas, Brandon D. “One-Shot Estimate of MRMC Variance: AUC.” Acad Radiol 13, no. 3 (2006): 353–62. https://doi.org/10.1016/j.acra.2005.11.030.
* Gallas, Brandon D. IMRMC v4.0: Application for Analyzing and Sizing MRMC Reader Studies. Silver Spring, MD, 2017. https://github.com/DIDSR/iMRMC/releases, https://cran.r-project.org/web/packages/iMRMC/index.html.

<h5>iRoeMetz</h5>

Desc: The iRoeMetz application can be used to simulate the reader scores for MRMC experiments via Monte Carlo methods given variance components of the ROC scores. The application also estimates the variance components of AUC and can calculate the variance components directly with numerical integration. The simulated experiments can be saved and used in MRMC variance analysis programs, such as iMRMC. The iRoeMetz application is a stand-alone, precompiled, license-free Java applications and the source code.
Expand All @@ -23,4 +28,8 @@ Desc: The iRoeMetz application can be used to simulate the reader scores for MRM

Desc: The R package iMRMC executes the iMRMC program which writes the results to the local files system, it reads the analysis results from the local file system, packs the analysis results into a list object, deletes the data and analysis results from the local file system, and returns the list object.

Here is one way to cite our work:
* Gallas, Brandon D., and Stephen L. Hillis. “Generalized Roe and Metz ROC Model: Analytic Link between Simulated Decision Scores and Empirical AUC Variances and Covariances.” J Med Img 1, no. 3 (2014): 031006. https://doi.org/doi:10.1117/1.JMI.1.3.031006.

[![Github All Releases](https://img.shields.io/github/downloads/DIDSR/iMRMC/total)]()

2 changes: 2 additions & 0 deletions Rpackage/iMRMC/.Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
^imrmcDir$
^README\.md$
^futureVignettes$
^README-submission-process\.md$
^cran-check\.md$
4 changes: 2 additions & 2 deletions Rpackage/iMRMC/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: iMRMC
Type: Package
Title: Multi-Reader, Multi-Case Analysis Methods (ROC, Agreement, and Other Metrics)
Version: 1.2.1
Version: 1.2.3
Author: Brandon Gallas
Maintainer: Brandon Gallas <[email protected]>
Description:
Expand All @@ -23,7 +23,7 @@ License: CC0
Encoding: UTF-8
SystemRequirements: Java JDK 1.7 or higher
LazyData: true
Depends: R (>= 2.10)
Depends: R (>= 3.5.0)
RoxygenNote: 7.0.2
Imports: stats
Suggests: testthat
4 changes: 3 additions & 1 deletion Rpackage/iMRMC/NEWS.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Please refer to https://github.com/DIDSR/iMRMC/blob/master/UPDATES_Rpackage_iMRMC.md
# iMRMC

Information on updates are managed here: https://github.com/DIDSR/iMRMC/blob/master/UPDATES_Rpackage_iMRMC.md
95 changes: 62 additions & 33 deletions Rpackage/iMRMC/R/iMRMC.R
Original file line number Diff line number Diff line change
Expand Up @@ -116,31 +116,55 @@ doIMRMC <- function(
iMRMCjarFullPath = NULL,
stripDatesForTests = FALSE){

if (is.null(workDir)) {
workDir <- normalizePath(tempdir())
# If workDir is not specified, it will be the R temp directory.
# If workDir is specified, create it.
if (is.null(workDir))
workDir <- normalizePath(tempdir(), winslash = "/")
else
dir.create(workDir, showWarnings = FALSE)

# The inputFile will hold the data for the java program
inputFile <- file.path(workDir, "input.imrmc")

# Check that data is provided
if (is.null(data) & is.null(fileName)) {
stop("You have not provided an input data frame or an input file.")
}
# Check that data is not provided twice.
if (!is.null(data) & !is.null(fileName)) {
stop("You cannot provide an input data frame AND an input file.")
}

# If fileName is specified make sure it exists.
# Copy the fileName to the inputFile in the workDir.
if (!is.null(fileName)) {
if (!file.exists(fileName)) {
print(paste("fileName = ", fileName))
stop("The full-path fileName provided does not exist.")
}
if (fileName == inputFile) {
print(paste("fileName = ", fileName))
stop("fileName equals the name of the temp inputFile. This is not allowed.")
}
file.copy(fileName, inputFile)
}

if (is.null(data)) {
if (is.null(fileName)) {
stop("ERROR: You have not provided an input data frame or an input file.")
} else {
flagWriteFile <- FALSE
}
} else {
if (!is.null(fileName)) {
stop("ERROR: You cannot provide and input data frame AND an input file.")
}

flagWriteFile <- TRUE
fileName <- file.path(workDir, "input.imrmc")
# Check the input data and write it to the inputFile in the workDir
if (!is.null(data)) {

# Write data frame to iMRMC input file
writeLines("BEGIN DATA:", con = fileName)
utils::write.table(data, fileName,
# Check that the input data has key columns: readerID, caseID, modalityID, score
if (length(setdiff(c("readerID", "caseID", "modalityID", "score"), names(data)))) {
stop("The data frame does not include the key columns: readerID, caseID, modalityID, score.")
}

# Write data frame to the inputFile
writeLines("BEGIN DATA:", con = inputFile)
utils::write.table(data[ , c("readerID", "caseID", "modalityID", "score")], inputFile,
quote = FALSE, row.names = FALSE, col.names = FALSE,
append = TRUE, sep = ", ")

}

if (is.null(iMRMCjarFullPath)) {
iMRMCjar <- "iMRMC-v4.0.3.jar"
pkgPath <- path.package("iMRMC", quiet = FALSE)
Expand All @@ -155,30 +179,39 @@ doIMRMC <- function(

# Run iMRMC
desc <- tryCatch(

system2(
"java",
args = c("-jar",
iMRMCjarFullPath,
fileName,
file.path(workDir, "imrmcDir")),
stdout = FALSE, stderr = TRUE),

args = c(
"-jar",
iMRMCjarFullPath,
inputFile,
file.path(workDir, "imrmcDir")
),
stdout = TRUE, stderr = TRUE
),

warning = function(w) {
cat("do_IMRMC WARNING\n")
warning(w)
},

error = function(e) {
cat("\ndoIMRMC ERROR\n")
cat("One possible reason is that you don't have java.\n")
cat("This software requires Java JDK 1.7 or higher.\n")
stop(e)
}

)

if (!file.exists(file.path(workDir, "imrmcDir", "AUCperReader.csv"))) {
cat(desc, sep = "\n")
stop()
}

# Retrieve the iMRMC results
perReader <- utils::read.csv(file.path(workDir, "imrmcDir", "AUCperReader.csv"))
perReader <- utils::read.csv(file.path(workDir, "imrmcDir", "AUCperReader.csv"))
Ustat <- utils::read.csv(file.path(workDir, "imrmcDir", "statAnalysis.csv"))
MLEstat <- utils::read.csv(file.path(workDir, "imrmcDir", "statAnalysisMLE.csv"))
ROCraw <- utils::read.csv(file.path(workDir, "imrmcDir", "ROCcurves.csv"),
Expand Down Expand Up @@ -211,13 +244,9 @@ doIMRMC <- function(
}

# Delete the content written to disk
if (workDir == normalizePath(tempdir())){
if (workDir == normalizePath(tempdir(), winslash = "/")) {
unlink(file.path(workDir, "imrmcDir"), recursive = TRUE)

if (flagWriteFile) {
unlink(fileName)
}

unlink(inputFile)
}

varDecomp <- list(
Expand Down
4 changes: 2 additions & 2 deletions Rpackage/iMRMC/R/limitsOfAgreement.R
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ laWRBM <- function(
result2 <- data.frame(
meanDiff = meanDiff, var.MeanDiff = var.MeanDiff, var.1obs = var.1obs,
ci95meanDiff.bot = ci95meanDiff.bot, ci95meanDiff.top = ci95meanDiff.top,
la.bot = la.bot, la.top = la.top )
la.bot = la.bot, la.top = la.top, stringsAsFactors = TRUE)

return(result2)

Expand Down Expand Up @@ -156,7 +156,7 @@ laBRBM <- function(
result2 <- data.frame(
meanDiff = meanDiff, var.MeanDiff = var.MeanDiff, var.1obs = var.Ar1cminusBr2c,
ci95meanDiff.bot = ci95meanDiff.bot, ci95meanDiff.top = ci95meanDiff.top,
la.bot = la.bot, la.top = la.top )
la.bot = la.bot, la.top = la.top, stringsAsFactors = TRUE )

return(result2)

Expand Down
6 changes: 4 additions & 2 deletions Rpackage/iMRMC/R/simMRMC.R
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ simMRMC <- function(simMRMC.config) {
readerID = readerID,
caseID = caseID,
modalityID = modalityID,
score = L_mu + L_cases + L_readers + L_reader.case
score = L_mu + L_cases + L_readers + L_reader.case,
stringsAsFactors = TRUE
)

}
Expand Down Expand Up @@ -256,7 +257,8 @@ sim.gRoeMetz <- function(config) {
readerID = rep("-1", nC.neg + nC.pos),
caseID = c(as.character(caseIDs.neg), as.character(caseIDs.pos)),
modalityID = rep("truth", nC.neg + nC.pos),
score = c(rep(0, nC.neg), rep(1, nC.pos))
score = c(rep(0, nC.neg), rep(1, nC.pos)),
stringsAsFactors = TRUE
)

# Simulate the modality independent random effects, negative cases
Expand Down
41 changes: 30 additions & 11 deletions Rpackage/iMRMC/R/uStats.R
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ uStat11.jointD <- function(
keyColumns = c("readerID", "caseID", "modalityID", "score")
) {

if (class(modalitiesToCompare) != "character") {
stop(paste(
"class(modalitiesToCompare) =", class(modalitiesToCompare),
"... The class should be character.")
)
}

if (kernelFlag == 1) {

if (length(modalitiesToCompare) != 2) {
Expand Down Expand Up @@ -182,7 +189,7 @@ uStat11.jointD <- function(
sumiD.A <- colSums(design.A)
sumiD.B <- colSums(design.B)

meanPerR <- data.frame(sumiS.A / sumiD.A, sumiS.B / sumiD.B)
meanPerR <- data.frame(sumiS.A / sumiD.A, sumiS.B / sumiD.B, stringsAsFactors = TRUE)
names(meanPerR) <- c(desc[1], desc[2])

# Declare the constituent parts of the variance decomposition
Expand All @@ -192,7 +199,8 @@ uStat11.jointD <- function(
c1r0 = c(0, 0, 0),
c0r1 = c(0, 0, 0),
c1r1 = c(0, 0, 0),
row.names = c("AB", "CD", "ABminusCD")
row.names = c("AB", "CD", "ABminusCD"),
stringsAsFactors = TRUE
)
denom.biased <- numer.biased

Expand Down Expand Up @@ -291,9 +299,9 @@ uStat11.jointD <- function(
var.AminusB <- var.A + var.B - 2 * coeff[3, ] %*% moments[3, ]

# Turn these matrices into data frames
moments <- data.frame(moments)
moments <- data.frame(moments, stringsAsFactors = TRUE)
names(moments) <- names(numer.biased)
coeff <- data.frame(coeff)
coeff <- data.frame(coeff, stringsAsFactors = TRUE)
names(coeff) <- names(numer.biased)

mean <- c(mean.A, mean.B, mean.A - mean.B)
Expand All @@ -303,7 +311,7 @@ uStat11.jointD <- function(
var.1obs <- moments$c1r1 - moments$c0r0
var.1obs[3] <- var.1obs[1] + var.1obs[2] - 2 * var.1obs[3]
names(var.1obs) <- desc
nCperR <- data.frame(sumiD.A, sumiD.B)
nCperR <- data.frame(sumiD.A, sumiD.B, stringsAsFactors = TRUE)
names(nCperR) <- desc[1:2]

#### Pack Results ####
Expand Down Expand Up @@ -339,6 +347,13 @@ uStat11.conditionalD <- function(
keyColumns = c("readerID", "caseID", "modalityID", "score")
) {

if (class(modalitiesToCompare) != "character") {
stop(paste(
"class(modalitiesToCompare) =", class(modalitiesToCompare),
"... The class should be character.")
)
}

# Initialize kernel and design matrices ####
if (kernelFlag == 1) {

Expand Down Expand Up @@ -390,7 +405,7 @@ uStat11.conditionalD <- function(
sumiS.A <- colSums(kernel.A)
sumiS.B <- colSums(kernel.B)

meanPerR <- data.frame(sumiS.A / sumiD.A, sumiS.B / sumiD.B)
meanPerR <- data.frame(sumiS.A / sumiD.A, sumiS.B / sumiD.B, stringsAsFactors = TRUE)
names(meanPerR) <- c(desc[1], desc[2])

# Reader weights for the reader-averged point estimate
Expand Down Expand Up @@ -586,14 +601,16 @@ uStat11.conditionalD <- function(
c0r0 = c(m.c0r0.AA, m.c0r0.BB, m.c0r0.AB),
c0r1 = c(m.c0r1.AA, m.c0r1.BB, m.c0r1.AB),
c1r0 = c(m.c1r0.AA, m.c1r0.BB, m.c1r0.AB),
c1r1 = c(m.c1r1.AA, m.c1r1.BB, m.c1r1.AB)
c1r1 = c(m.c1r1.AA, m.c1r1.BB, m.c1r1.AB),
stringsAsFactors = TRUE
)

coeff <- data.frame(
c0r0 = c(c.c0r0.AA, c.c0r0.BB, c.c0r0.AB),
c0r1 = c(c.c0r1.AA, c.c0r1.BB, c.c0r1.AB),
c1r0 = c(c.c1r0.AA, c.c1r0.BB, c.c1r0.AB),
c1r1 = c(c.c1r1.AA, c.c1r1.BB, c.c1r1.AB)
c1r1 = c(c.c1r1.AA, c.c1r1.BB, c.c1r1.AB),
stringsAsFactors = TRUE
)

mean <- c(mean.A, mean.B, mean.A - mean.B)
Expand All @@ -603,7 +620,7 @@ uStat11.conditionalD <- function(
var.1obs <- moments$c1r1 - moments$c0r0
var.1obs[3] <- var.1obs[1] + var.1obs[2] - 2 * var.1obs[3]
names(var.1obs) <- desc
nCperR <- data.frame(sumiD.A, sumiD.B)
nCperR <- data.frame(sumiD.A, sumiD.B, stringsAsFactors = TRUE)
names(nCperR) <- desc[1:2]

result <- list(
Expand Down Expand Up @@ -650,7 +667,8 @@ uStat11.identity <- function(
df <- data.frame(readerID = factor(df.input[[keyColumns[1]]]),
caseID = factor(df.input[[keyColumns[[2]]]]),
modalityID = factor(df.input[[keyColumns[[3]]]]),
score = df.input[[keyColumns[[4]]]]
score = df.input[[keyColumns[[4]]]],
stringsAsFactors = TRUE
)

# Parse out data frames for each modality
Expand Down Expand Up @@ -708,7 +726,8 @@ uStat11.diff <- function(
df <- data.frame(readerID = factor(df.input[[keyColumns[1]]]),
caseID = factor(df.input[[keyColumns[[2]]]]),
modalityID = factor(df.input[[keyColumns[[3]]]]),
score = df.input[[keyColumns[[4]]]]
score = df.input[[keyColumns[[4]]]],
stringsAsFactors = TRUE
)

# Parse out data frames for each modality
Expand Down
Loading

0 comments on commit 339352d

Please sign in to comment.