Nothing
# Test cases for function 'VCAinference'
#
# Author: André Schützenmeister
#
# Note: Confidence Intervals for all variance components but total are compared
# to results of SAS 9.2 PROC MIXED (method=Type1, cl options, 4 decimal digits).
# CI-limits for total VC are compared to Roche Diagnostics SAS Intranet Module VCA
# results (if included in the testcase).used within the Satterthwaite approximation
# For balanced data the Fisher-Information matrix used as approximation of the
# covariance-matrix of VCs is identical to the implemented covariance matrix of
# VCs (see 'anovaVCA', 'anovaVCAnub', 'VCAinference' for details).
#
########################################################################################################################
cat("\n\n***************************************************************************")
cat("\nVariance Component Analysis (VCA) - test cases for function 'VCAinference'.")
cat("\n***************************************************************************\n\n")
# load data and generate datasets where negative VC estimates occur
data(dataEP05A2_1)
data1 <- dataEP05A2_1
set.seed(1)
data1$y <- data1$y + rnorm(80,,5)
data(dataEP05A2_2)
data2 <- dataEP05A2_2
set.seed(2)
data2$y <- data2$y + rnorm(80,,8)
data(dataEP05A2_3)
data3 <- dataEP05A2_3
set.seed(3)
data3$y <- data3$y + rnorm(80,,10)
data(dataEP05A3_MS_1)
data(dataEP05A3_MS_2)
data(dataEP05A3_MS_3)
# check EP05-A2 20/2/2 output for balanced data (total variance, error variance)
TF001.VCAinference.constrained_CIs.balanced <- function()
{
fit1 <- anovaVCA(y~day/run, Data=dataEP05A2_1, NegVC=TRUE, MME=TRUE)
INF1 <- VCAinference(fit1, VarVC=TRUE, excludeNeg=FALSE, constrainCI=TRUE)
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "LCL"]), 4), c(2.4156, 0, 0, 1.3167)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "UCL"]), 4), c(4.7767, 1.0322, 2.8455, 3.1980)) # CI VC two-sided upper limits
fit2 <- anovaVCA(y~day/run, Data=dataEP05A2_2, NegVC=TRUE, MME=TRUE)
INF2 <- VCAinference(fit2, VarVC=TRUE, excludeNeg=FALSE, constrainCI=TRUE)
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "LCL"]), 4), c(5.9669, 0, 0, 2.5077)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "UCL"]), 4), c(12.7046, 4.8921, 5.8428, 6.0906)) # CI VC two-sided upper limits
fit3 <- anovaVCA(y~day/run, Data=dataEP05A2_3, NegVC=TRUE, MME=TRUE)
INF3 <- VCAinference(fit3, VarVC=TRUE, excludeNeg=FALSE, constrainCI=TRUE)
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "LCL"]), 4), c(24.8957, 0, 0, 10.9764)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "UCL"]), 4), c(54.8935, 25.6818, 17.0897, 26.6590)) # CI VC two-sided upper limits
}
TF002.VCAinference.unconstrained_CIs.balanced <- function()
{
fit1 <- anovaVCA(y~day/run, Data=dataEP05A2_1, NegVC=TRUE, MME=TRUE)
INF1 <- VCAinference(fit1, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE)
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "LCL"]), 4), c(2.4156, -1.0300, -0.1565, 1.3167)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "UCL"]), 4), c(4.7767, 1.0322, 2.8455, 3.1980)) # CI VC two-sided upper limits
fit2 <- anovaVCA(y~day/run, Data=dataEP05A2_2, NegVC=TRUE, MME=TRUE)
INF2 <- VCAinference(fit2, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE)
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "LCL"]), 4), c(5.9669, -1.1845, -0.1907, 2.5077)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "UCL"]), 4), c(12.7046, 4.8921, 5.8428, 6.0906)) # CI VC two-sided upper limits
fit3 <- anovaVCA(y~day/run, Data=dataEP05A2_3, NegVC=TRUE, MME=TRUE)
INF3 <- VCAinference(fit3, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE)
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "LCL"]), 4), c(24.8957, -1.2196, -3.0273, 10.9764)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "UCL"]), 4), c(54.8935, 25.6818, 17.0897, 26.6590)) # CI VC two-sided upper limits
}
TF003.VCAinference.negative_VC.balanced <- function()
{
# constrainCI has to be TRUE whenever any VC-estimates were set to 0
fit1 <- anovaVCA(y~day/run, data1, MME=TRUE)
INF1 <- VCAinference(fit1, VarVC=TRUE, constrainCI=FALSE)
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "LCL"]), 4), c( 24.2184, NA, 0.0000, 14.4422))
# if CIs for originally negative VC estimates should not be excluded, always constrain them to zero if VC estimates were constrained
fit2 <- anovaVCA(y~day/run, data1, MME=TRUE)
INF2 <- VCAinference(fit2, VarVC=TRUE, excludeNeg=FALSE)
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "LCL"]), 4), c(24.2184, 0.0000, 0.0000, 14.4422))
# CIs of results with negative VC estimates, which are reported unconstrained (NegVC=TRUE in anovaVCA), cannot be constrained
# they can only be excluded (Default)
fit3 <- anovaVCA(y~day/run, data1, NegVC=TRUE, MME=TRUE)
INF3 <- VCAinference(fit3, VarVC=TRUE, excludeNeg=TRUE)
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "LCL"]), 4), c(19.2231, NA, -3.0623, 14.4422))
# or not
fit4 <- anovaVCA(y~day/run, data1, NegVC=TRUE, MME=TRUE)
INF4 <- VCAinference(fit4, VarVC=TRUE, excludeNeg=FALSE)
checkEquals(round(as.numeric(INF4$ConfInt$VC$TwoSided[, "LCL"]), 4), c(19.2231, -14.1191, -3.0623, 14.4422))
}
# check EP05-A3 3/5/5 Multi-Site output for balanced data (total variance, error variance)
TF004.VCAinference.VC_CI.balanced <- function()
{
fit1 <- anovaVCA(y~site/day, Data=dataEP05A3_MS_1, NegVC=TRUE, MME=TRUE)
INF1 <- VCAinference(fit1, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE)
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "LCL"]), 4), c(2.0437, -1.2939, -0.3148, 1.6365)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "UCL"]), 4), c(8.1959, 3.3287, 1.0065, 3.3674)) # CI VC two-sided upper limits
fit2 <- anovaVCA(y~site/day, Data=dataEP05A3_MS_2, NegVC=TRUE, MME=TRUE)
INF2 <- VCAinference(fit2, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE) # total not tested
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[-1, "LCL"]), 4), c(-1.6806, -0.4157, 2.6842)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[-1, "UCL"]), 4), c( 3.7022, 2.4723, 5.5231)) # CI VC two-sided upper limits
fit3 <- anovaVCA(y~site/day, Data=dataEP05A3_MS_3, NegVC=TRUE, MME=TRUE)
INF3 <- VCAinference(fit3, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE) # total not tested
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[-1, "LCL"]), 4), c(-20.5980, -1.4056, 10.8222)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[-1, "UCL"]), 4), c( 56.5796, 12.2530, 22.2685)) # CI VC two-sided upper limits
}
# test one-sided CIs against values obtained via Excel-based PrecPerf Reports
TF005.VCAinference.WinCAEv_PrecPerf.SD_CI <- function()
{
data_1 <- data.frame(day=c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21),
run=c(1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2),
y=c(106.2, 106.6, 106.2, 106.1, 106.8, 106.9, 107.1, 107, 107.5, 107.5, 107.2, 107, 107.8, 107.5, 106.9, 106.8, 107.1, 106.9, 106.1, 105.7, 106.5, 106.3, 105.8, 105.8, 106, 106, 105.4, 105.4, 105.4, 105.3, 104.6, 104.5, 105.2, 105.3, 104.9, 104.8, 105.1, 105.1, 104.3, 104.3, 104.5, 104.7, 104.1, 104, 104.1, 104.1, 103.4, 103.3, 103.3, 103.2, 102.6, 102.6, 103, 103.1, 102.5, 102.6, 102.9, 102.9, 102.3, 101.9, 102.5, 102.6, 102.2, 102.2, 102.5, 102.5, 102.3, 102.1, 105.5, 105.6, 105.3, 105.5, 106.5, 106.5, 106.5, 106.5, 108.1, 108.1, 108.3, 108.5, 104.9, 105.7, 105.2, 105.7))
res1 <- anovaVCA(y~day/run, data_1)
inf1 <- VCAinference(res1)
checkEquals(round(as.numeric(inf1$ConfInt$SD$OneSided["total", 2:3]), 8), c(1.45561309, 2.43889695))
checkEquals(round(as.numeric(inf1$ConfInt$SD$OneSided["error", 2:3]), 8), c(0.12750817, 0.18324098))
}
TF006.VCAinference.WinCAEv_PrecPerf.SD_CI <- function()
{
data_2 <-data.frame(day=c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21),
run=c(1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2),
y=c(107.7,107.4,107.3,107.5,105.7,105.8,105,104.9,104.5,105,104.9,104.8,105.4,105.3,105.2,105.3,105.6,105.5,104.9,104.9,105,104.7,104.1,104.1,104.6,104.7,104,104,104.3,104.5,104.1,104,104.5,104.3,103.8,103.8,104.1,104.3,103.9,103.7,104.1,104.1,103.3,103.2,103.5,103.5,102.6,102.5,102.7,102.8,102,101.8,102.4,102.2,101.7,101.7,102,102.1,101.4,101.3,104.8,105,104.2,104.1,104.1,104.2,103.4,103.6,104.5,104.7,104.5,104.2,105.2,105.3,104.6,104.6,105.2,105.1,104.6,104.4,103.9,103.8,103.9,103.7))
res2 <- anovaVCA(y~day/run, data_2)
inf2 <- VCAinference(res2)
checkEquals(round(as.numeric(inf2$ConfInt$SD$OneSided["total", 2:3]), 8), c(1.05907281, 1.74636429))
checkEquals(round(as.numeric(inf2$ConfInt$SD$OneSided["error", 2:3]), 8), c(0.10075071, 0.14478805))
}
### check confidence intervals of some crossed-nested designs (balanced and unbalanced)
# compare numerical equivalence of confidence intervals of VCs to SAS PROC MIXED results
# using following SAS-code:
#
# proc mixed data=sample method=type1 asycov cl;
# class lot device day run;
# model y=;
# random lot device lot*device*day lot*device*day*run;
# run;
TF007.VCAinference.CrossedNested.VC_CI.balanced <- function()
{
data(VCAdata1)
sample1 <- VCAdata1[which(VCAdata1$sample==1),]
sample1$device <- gl(3,28,252) # add device variable
set.seed(505)
sample1$y <- sample1$y + rep(rep(rnorm(3,,.25), c(28,28,28)),3) # add error component for device
# write.table(sample1UB, file="sample1UB.txt", quote=FALSE, row.names=FALSE, col.names=TRUE, sep="\t") # export data, import to SAS and apply SAS-code given above
res1 <- anovaVCA(y~lot+device+(lot:device:day)/run, sample1)
inf1 <- VCAinference(res1, VarVC=TRUE, constrainCI=FALSE, ci.method="sas")
CIs <- inf1$ConfInt$VC$TwoSided
CIs <- as.matrix(CIs[,-1])
colnames(CIs) <- NULL
checkEquals(round(CIs["lot",], 5), c(-0.01847, 0.04951)) # round to precision of SAS PROC MIXED output
checkEquals(round(CIs["device",], 5), c(-0.06322, 0.1875))
checkEquals(round(CIs["lot:device:day",], 5), c(-0.00399, 0.02910))
checkEquals(round(CIs["lot:device:day:run",], 5), c( 0.03282, 0.06865))
checkEquals(round(CIs["error",], 6), c( 0.000913, 0.001500))
}
# unbalanced data is obtained using following strategy:
#
# data sample1UB;
# set sample1;
# obs = _N_;
# if obs in (11,25,26,41,50) then delete;
# run;
#
# and then running the PROC MIXED code shown above.
TF008.VCAinference.CrossedNested.VC_CI.unbalanced <- function()
{
data(VCAdata1)
sample1 <- VCAdata1[which(VCAdata1$sample==1),]
sample1$device <- gl(3,28,252) # add device variable
set.seed(505)
sample1$y <- sample1$y + rep(rep(rnorm(3,,.25), c(28,28,28)),3) # add error component for device
sample1 <- sample1[-c(11,25,26,41,50),]
# write.table(sample1UB, file="sample1UB.txt", quote=FALSE, row.names=FALSE, col.names=TRUE, sep="\t") # export data, import to SAS and apply SAS-code given above
res1 <- anovaVCA(y~lot+device+(lot:device:day)/run, sample1)
inf1 <- VCAinference(res1, VarVC=TRUE, constrainCI=FALSE, ci.method="sas")
CIs <- inf1$ConfInt$VC$TwoSided
CIs <- as.matrix(CIs[,-1])
colnames(CIs) <- NULL
cat("\n\nSAS PROC MIXED uses the inverse of the Fisher-Information Matrix as approximation of Covariance-Matrix of Variance Components.")
cat("\nThis is equal to the one obtained via ANOVA-approach stated in \"Variance Components\" (Searle et al. 1991) in case")
cat("\nof balanced designs, otherwise Var(VC) of both results may differ:\n\n")
CImat <- matrix(NA, ncol=9, nrow=5)
colnames(CImat) <- c("SAS_Est", "R_Est", "SAS_LCL", "R_LCL", "SAS_UCL", "R_UCL", "Est_Diff", "LCL_Diff", "UCL_Diff")
rownames(CImat) <- rownames(CIs)[2:6]
CImat[,1] <- c(0.01377, 0.06190, 0.01235, 0.05125, 0.001180)
CImat[,2] <- round(res1$aov.tab[-1, "VC"], c(5,5,5,5,6))
CImat[,3] <- c(-0.01375, -0.06234, -0.00418, 0.03311, 0.000932)
CImat[,4] <- round(CIs[2:6, 1], c(5,5,5,5,6))
CImat[,5] <- c(0.04128, 0.1861, 0.02887, 0.06940, 0.001543)
CImat[,6] <- round(CIs[2:6, 2], c(5,4,5,5,6))
CImat[,7] <- CImat[,"SAS_Est"] - CImat[,"R_Est"]
CImat[,8] <- CImat[,"SAS_LCL"] - CImat[,"R_LCL"]
CImat[,9] <- CImat[,"SAS_UCL"] - CImat[,"R_UCL"]
checkEquals(round(CIs["error",], 6), c( 0.000932, 0.001543))
print(CImat)
}
TF009.VCAinference.CrossedNested.VC_CI.balanced <- function()
{
data(VCAdata1)
sample2 <- VCAdata1[which(VCAdata1$sample==2),]
sample2$device <- gl(3,28,252) # add device variable
set.seed(511)
sample2$y <- sample2$y + rep(rep(rnorm(3,,.25), c(28,28,28)),3) # add error component for device
# write.table(sample1UB, file="sample1UB.txt", quote=FALSE, row.names=FALSE, col.names=TRUE, sep="\t") # export data, import to SAS and apply SAS-code given above
res2 <- anovaVCA(y~lot+device+(lot:device:day)/run, sample2)
inf2 <- VCAinference(res2, VarVC=TRUE, constrainCI=FALSE, ci.method="sas")
CIs <- inf2$ConfInt$VC$TwoSided
CIs <- as.matrix(CIs[,-1])
colnames(CIs) <- NULL
checkEquals(round(CIs["lot",], 4), c(-0.2240, 0.6220)) # round to precision of SAS PROC MIXED output
checkEquals(round(CIs["device",], 4), c(-0.4456, 1.3055))
checkEquals(round(CIs["lot:device:day",], 4), c( 0.1857, 0.4437))
checkEquals(round(CIs["lot:device:day:run",], 5), c( 0.02677, 0.08087))
checkEquals(round(CIs["error",], 5), c( 0.03495, 0.05738))
}
TF010.VCAinference.CrossedNested.VC_CI.unbalanced <- function()
{
data(VCAdata1)
sample2 <- VCAdata1[which(VCAdata1$sample==2),]
sample2$device <- gl(3,28,252) # add device variable
set.seed(511)
sample2$y <- sample2$y + rep(rep(rnorm(3,,.25), c(28,28,28)),3) # add error component for device
sample2 <- sample2[-c(1,5,36,39,51),]
# write.table(sample1UB, file="sample1UB.txt", quote=FALSE, row.names=FALSE, col.names=TRUE, sep="\t") # export data, import to SAS and apply SAS-code given above
res2 <- anovaVCA(y~lot+device+(lot:device:day)/run, sample2)
inf2 <- VCAinference(res2, VarVC=TRUE, constrainCI=FALSE, ci.method="sas")
CIs <- inf2$ConfInt$VC$TwoSided
CIs <- as.matrix(CIs[,-1])
colnames(CIs) <- NULL
cat("\n\nSAS PROC MIXED uses the inverse of the Fisher-Information Matrix as approximation of Covariance-Matrix of Variance Components.")
cat("\nThis is equal to the one obtained via ANOVA-approach stated in \"Variance Components\" (Searle et al. 1991) in case")
cat("\nof balanced designs, otherwise Var(VC) of both results may differ:\n\n")
CImat <- matrix(NA, ncol=9, nrow=5)
colnames(CImat) <- c("SAS_Est", "R_Est", "SAS_LCL", "R_LCL", "SAS_UCL", "R_UCL", "Est_Diff", "LCL_Diff", "UCL_Diff")
rownames(CImat) <- rownames(CIs)[2:6]
CImat[,1] <- c(0.1892, 0.4359, 0.3178, 0.05724, 0.04108)
CImat[,2] <- round(res2$aov.tab[-1, "VC"], c(4,4,4,5,5))
CImat[,3] <- c(-0.1909, -0.4608, 0.1860, 0.02931, 0.03241)
CImat[,4] <- round(CIs[2:6, 1],c(4,4,4,5,5))
CImat[,5] <- c(0.5692, 1.3326, 0.4496, 0.08517, 0.05376)
CImat[,6] <- round(CIs[2:6, 2], c(4,4,4,5,5))
CImat[,7] <- CImat[,"SAS_Est"] - CImat[,"R_Est"]
CImat[,8] <- CImat[,"SAS_LCL"] - CImat[,"R_LCL"]
CImat[,9] <- CImat[,"SAS_UCL"] - CImat[,"R_UCL"]
checkEquals(round(CIs["error",], 5), c( 0.03241, 0.05376))
print(CImat)
}
TF011.VCAinference.CrossedNested.VC_CI.balanced <- function()
{
data(VCAdata1)
sample3 <- VCAdata1[which(VCAdata1$sample==3),]
sample3$device <- gl(3,28,252) # add device variable
set.seed(519)
sample3$y <- sample3$y + rep(rep(rnorm(3,,.25), c(28,28,28)),3) # add error component for device
# write.table(sample1UB, file="sample1UB.txt", quote=FALSE, row.names=FALSE, col.names=TRUE, sep="\t") # export data, import to SAS and apply SAS-code given above
res3 <- anovaVCA(y~lot+device+(lot:device:day)/run, sample3, NegVC=TRUE)
inf3 <- VCAinference(res3, VarVC=TRUE, constrainCI=FALSE, excludeNeg=FALSE, ci.method="sas")
CIs <- inf3$ConfInt$VC$TwoSided
CIs <- as.matrix(CIs[,-1])
colnames(CIs) <- NULL
checkEquals(round(CIs["lot",], c(5,6)), c(-0.00168, 0.000049)) # round to precision of SAS PROC MIXED output
checkEquals(round(CIs["device",], c(5,4)), c(-0.05672, 0.1700))
checkEquals(round(CIs["lot:device:day",], c(5,6)), c(-0.03297, 0.001022))
checkEquals(round(CIs["lot:device:day:run",], c(5,4)), c( 0.05327, 0.1106))
checkEquals(round(CIs["error",], c(6,6)), c( 0.000263, 0.000432))
}
TF012.VCAinference.CrossedNested.VC_CI.unbalanced <- function()
{
data(VCAdata1)
sample3 <- VCAdata1[which(VCAdata1$sample==3),]
sample3$device <- gl(3,28,252) # add device variable
set.seed(519)
sample3$y <- sample3$y + rep(rep(rnorm(3,,.25), c(28,28,28)),3) # add error component for device
sample3 <- sample3[-c(9,10,11,29,30),]
# write.table(sample1UB, file="sample1UB.txt", quote=FALSE, row.names=FALSE, col.names=TRUE, sep="\t") # export data, import to SAS and apply SAS-code given above
res3 <- anovaVCA(y~lot+device+(lot:device:day)/run, sample3, NegVC=TRUE)
inf3 <- VCAinference(res3, VarVC=TRUE, constrainCI=FALSE, excludeNeg=FALSE, ci.method="sas")
CIs <- inf3$ConfInt$VC$TwoSided
CIs <- as.matrix(CIs[,-1])
colnames(CIs) <- NULL
cat("\n\nSAS PROC MIXED uses the inverse of the Fisher-Information Matrix as approximation of Covariance-Matrix of Variance Components.")
cat("\nThis is equal to the one obtained via ANOVA-approach stated in \"Variance Components\" (Searle et al. 1991) in case")
cat("\nof balanced designs, otherwise Var(VC) of both results may differ:\n\n")
CImat <- matrix(NA, ncol=9, nrow=5)
colnames(CImat) <- c("SAS_Est", "R_Est", "SAS_LCL", "R_LCL", "SAS_UCL", "R_UCL", "Est_Diff", "LCL_Diff", "UCL_Diff")
rownames(CImat) <- rownames(CIs)[2:6]
CImat[,1] <- c(-0.00085, 0.05804, -0.01741, 0.08400, 0.000337)
CImat[,2] <- round(res3$aov.tab[-1, "VC"], c(5,5,5,5,6))
CImat[,3] <- c(-0.00154, -0.05762, -0.03482, 0.05394, 0.000266)
CImat[,4] <- round(CIs[2:6, 1],c(5,5,5,5,6))
CImat[,5] <- c(-0.00017, 0.1737, -0.00000325, 0.1141, 0.000440)
CImat[,6] <- round(CIs[2:6, 2], c(5,4,8,4,6))
CImat[,7] <- CImat[,"SAS_Est"] - CImat[,"R_Est"]
CImat[,8] <- CImat[,"SAS_LCL"] - CImat[,"R_LCL"]
CImat[,9] <- CImat[,"SAS_UCL"] - CImat[,"R_UCL"]
checkEquals(round(CIs["error",], 6), c( 0.000266, 0.000440))
print(CImat)
}
# Test Satterthwaite methodology for confidence intervals of all variance components. This is different from the SAS PROC MIXED
# methodology, whenever Type1 estimation method is chosen, which is tested in all other test functions above. Here, all VC CIs
# are constructed using the Chi-Squared distribution and DFs are approximated according to Satterthwaite.
#
# For balanced designs, CIs are equal of those constructed by SAS PROC MIXED with method=REML. In this setting, CIs are constructed
# using the "Satterthwaite methodology".
TF013.anovaVCA.Satt_methodology_for_CI.balanced <- function()
{
data(dataEP05A2_2)
res <- anovaVCA(y~day/run, dataEP05A2_2)
inf <- VCAinference(res, VarVC=TRUE, ci.method="satterthwaite")
checkEquals(round(as.numeric(inf$ConfInt$VC$TwoSided[-1, "LCL"]), 4), c(0.5835, 1.2203, 2.5077))
checkEquals(round(as.numeric(inf$ConfInt$VC$TwoSided[-1, "UCL"]), 4), c(28.5302, 12.1410, 6.0906))
}
TF014.anovaVCA.Satt_methodology_for_CI.balanced <- function()
{
data(dataEP05A2_3)
res <- anovaVCA(y~day/run, dataEP05A2_3)
inf <- VCAinference(res, VarVC=TRUE, ci.method="satterthwaite")
checkEquals(round(as.numeric(inf$ConfInt$VC$TwoSided[-1, "LCL"]), 4), c(5.1779, 2.4638, 10.9764))
checkEquals(round(as.numeric(inf$ConfInt$VC$TwoSided[-1, "UCL"]), 4), c(55.8104, 64.3402, 26.6590))
}
# now checking mixed models, where day is fixed
TF015.anovaMM.Satt_methodology.balanced <- function()
{
data(dataEP05A2_2)
res <- anovaMM(y~day/(run), dataEP05A2_2)
inf <- VCAinference(res, VarVC=TRUE, ci.method="satterthwaite")
checkEquals(round(as.numeric(inf$ConfInt$VC$TwoSided[-1, "LCL"]), 4), c(1.2203, 2.5077))
checkEquals(round(as.numeric(inf$ConfInt$VC$TwoSided[-1, "UCL"]), 4), c(12.1410, 6.0906))
}
TF016.anovaMM.Satt_methodology.balanced <- function()
{
data(dataEP05A2_3)
res <- anovaMM(y~day/(run), dataEP05A2_3)
inf <- VCAinference(res, VarVC=TRUE, ci.method="satterthwaite")
checkEquals(round(as.numeric(inf$ConfInt$VC$TwoSided[-1, "LCL"]), 4), c(2.4638, 10.9764))
checkEquals(round(as.numeric(inf$ConfInt$VC$TwoSided[-1, "UCL"]), 4), c(64.3402, 26.6590))
}
# This test checks whether point estimates exceeding the bounds of a confidence interval
# are correctly set to NA.
TF017.anovaVCA.Est_outsided_CI <- function()
{
data(ReproData1) # input data
fit <- anovaVCA(value~Site/Day/Run, ReproData1)
inf <- tryCatch(VCAinference(fit, ci.method="satterthwaite"), # warning should be issued
warning=function(w) w )
checkTrue(is(inf, "warning"))
inf <- VCAinference(fit, ci.method="satterthwaite")
infVC <- print(inf, what="VC")
checkTrue(is.na(infVC["Site:Day:Run", "CI LCL"]))
checkTrue(is.na(infVC["Site:Day:Run", "CI UCL"]))
checkTrue(is.na(infVC["Site:Day:Run", "One-Sided LCL"]))
}
# check EP05-A2 20/2/2 output for balanced data (total variance, error variance)
TF018.VCAinference.constrained_CIs.balanced <- function()
{
fit1 <- remlVCA(y~day/run, Data=dataEP05A2_1)
INF1 <- VCAinference(fit1, VarVC=TRUE, excludeNeg=FALSE, constrainCI=TRUE)
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "LCL"]), 4), c(2.4156, 0, 0, 1.3167)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "UCL"]), 4), c(4.7767, 1.0322, 2.8455, 3.1980)) # CI VC two-sided upper limits
fit2 <- remlVCA(y~day/run, Data=dataEP05A2_2)
INF2 <- VCAinference(fit2, VarVC=TRUE, excludeNeg=FALSE, constrainCI=TRUE)
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "LCL"]), 4), c(5.9669, 0, 0, 2.5077)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "UCL"]), 4), c(12.7046, 4.8921, 5.8428, 6.0906)) # CI VC two-sided upper limits
fit3 <- remlVCA(y~day/run, Data=dataEP05A2_3)
INF3 <- VCAinference(fit3, VarVC=TRUE, excludeNeg=FALSE, constrainCI=TRUE)
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "LCL"]), 4), c(24.8957, 0, 0, 10.9764)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "UCL"]), 4), c(54.8935, 25.6818, 17.0897, 26.6590)) # CI VC two-sided upper limits
}
TF019.VCAinference.unconstrained_CIs.balanced <- function()
{
fit1 <- remlVCA(y~day/run, Data=dataEP05A2_1)
INF1 <- VCAinference(fit1, excludeNeg=FALSE, constrainCI=FALSE)
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "LCL"]), 4), c(2.4156, -1.0300, -0.1565, 1.3167)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "UCL"]), 4), c(4.7767, 1.0322, 2.8455, 3.1980)) # CI VC two-sided upper limits
fit3 <- remlVCA(y~day/run, Data=dataEP05A2_3)
INF3 <- VCAinference(fit3, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE)
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "LCL"]), 4), c(24.8957, -1.2196, -3.0273, 10.9764)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[, "UCL"]), 4), c(54.8935, 25.6818, 17.0897, 26.6590)) # CI VC two-sided upper limits
}
TF020.VCAinference.balanced.REML.satterthwaite <- function()
{
# constrainCI has to be TRUE whenever any VC-estimates were set to 0
fit1 <- remlVCA(y~day/run, data1)
INF1 <- VCAinference(fit1, ci.method="satt") # need Satterthwaite here to have SAS PROC MIXED reference results
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "LCL"]), 2), c( 19.64, NA, 1.51, 14.44))
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "UCL"]), 2), c( 37.24, NA, 89.63, 35.08))
fit2 <- remlVCA(y~day/run, data2)
INF2 <- VCAinference(fit2, ci.method="satt")
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "LCL"]), 4), c( 63.1044 , NA, NA, 63.1044 ))
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[, "UCL"]), 4), c( 118.2015, NA, NA, 118.2015))
}
# check EP05-A3 3/5/5 Multi-Site output for balanced data (total variance, error variance)
TF021.VCAinference.VC_CI.balanced.REML <- function()
{
fit1 <- remlVCA(y~site/day, Data=dataEP05A3_MS_1)
INF1 <- VCAinference(fit1, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE)
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "LCL"]), 4), c(2.0437, -1.2939, -0.3148, 1.6365)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF1$ConfInt$VC$TwoSided[, "UCL"]), 4), c(8.1959, 3.3287, 1.0065, 3.3674)) # CI VC two-sided upper limits
fit2 <- remlVCA(y~site/day, Data=dataEP05A3_MS_2)
INF2 <- VCAinference(fit2, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE) # total not tested
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[-1, "LCL"]), 4), c(-1.6806, -0.4157, 2.6842)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF2$ConfInt$VC$TwoSided[-1, "UCL"]), 4), c( 3.7022, 2.4723, 5.5231)) # CI VC two-sided upper limits
fit3 <- remlVCA(y~site/day, Data=dataEP05A3_MS_3)
INF3 <- VCAinference(fit3, VarVC=TRUE, excludeNeg=FALSE, constrainCI=FALSE) # total not tested
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[-1, "LCL"]), 4), c(-20.5980, -1.4056, 10.8222)) # CI VC two-sided lower limits
checkEquals(round(as.numeric(INF3$ConfInt$VC$TwoSided[-1, "UCL"]), 4), c( 56.5796, 12.2530, 22.2685)) # CI VC two-sided upper limits
}
# check test case collection against SAS PROC MIXED method=type1 results
noTF <- 21 # number of last test function
########## create unit-test functions for SAS-reference data of the real world dataset
# All leading and trailing zeros are removed as well as all non-digits (decimal point, "e-" in exponential form).
# Remaining digits are counted and returned as number of signficant digits.
Nsignif <- function(x){ return( nchar(gsub("0+$", "", gsub("^0+", "", sub("e-..$", "", sub("\\.", "", x))))) )} # determine the number of significant digits
TestPrecision <- 1e-12
data(realData)
### note, "tc.path" defined in RunAllTests.R
SASrefModel1 <- read.delim(paste(tc.path, "SASresultsRealData_Model1_by_PID_Lot.txt", sep="/"), header=TRUE)
by_PID_Lot <- realData[,c("PID", "lot")]
by_PID_Lot <- unique(by_PID_Lot)
by_PID_Lot$PID <- as.character(by_PID_Lot$PID)
by_PID_Lot$lot <- as.character(by_PID_Lot$lot)
# Function performs tests for each combination of PID and lot in the real-world dataset
# applying model1:
model1 <- y~calibration/day/run
generic.test.function <- function(Data, prec=NULL)
{
PID <- Data$PID[1]
Lot <- Data$lot[1]
cat("\n>>> REAL-DATA MODEL 1: Check against SAS PROC MIXED VCA reference results for PID =",PID, " and Lot =", Lot )
cat("\n\nEquivalence of analysis results tested for:\n")
cat("\n\t-all variance component (VC) estimates")
cat("\n\t-confidence interval of error VC (LCL, UCL)")
if(PID == 5 && Lot == 3 || PID == 3 && Lot == 1)
{
cat("\n\nDue to numerical reasons of representing floating point numbers as approximations,")
cat("\ni.e. 0.50125 represented as 0.512499999..., this test-case has larger precision value (e-03).")
prec <- 1e-03
}
cat("\n\nnumerical tolerance:", prec, "(R-results element-wise rounded to the number of significant digits of SAS PROC MIXED results)\n")
SASresult <- SASrefModel1[which(SASrefModel1$PID == PID & SASrefModel1$lot == Lot),]
Rresult <- anovaVCA(model1, Data, NegVC=TRUE)
RinfRes <- VCAinference(Rresult, VarVC=TRUE, constrainCI=FALSE)$ConfInt$VC$TwoSided
if(as.integer(as.character(PID)) == 2 && as.integer(as.character(Lot)) == 3)
{
cat("\n\nUse numeric precision of 1e-03 now!\n\n")
prec <- 1e-03
cat("R-Results:\n")
print(Rresult)
cat("\n\nSAS-Results:\n")
print(SASresult)
cat("\n\n")
}
nr <- nrow(Rresult$aov.tab)
# actually check SAS- and R-results
for(i in 2:nr)
{
checkEquals(signif(Rresult$aov.tab[i, "VC"], Nsignif(SASresult[i-1, "Estimate"])), SASresult[i-1, "Estimate"], # check equality of all VC-estimates
tolerance=prec)
if(i == 5) # also check CI-limits of error-VC
{
checkEquals(signif(RinfRes[i, "LCL"], Nsignif(SASresult[i-1, "Lower"])), SASresult[i-1, "Lower"],
tolerance=prec)
checkEquals(signif(RinfRes[i, "UCL"], Nsignif(SASresult[i-1, "Upper"])), SASresult[i-1, "Upper"],
tolerance=prec)
}
}
cat("\n\nSAS PROC MIXED uses the inverse of the Fisher-Information Matrix as approximation of Covariance-Matrix of Variance Components.")
cat("\nThis is equal to the one obtained via ANOVA-approach stated in \"Variance Components\" (Searle et al. 1991) in case")
cat("\nof balanced designs, otherwise Var(VC) of both results may differ:\n\n")
CImat <- matrix(NA, ncol=6, nrow=4)
colnames(CImat) <- c("SAS_LCL", "R_LCL", "SAS_UCL", "R_UCL", "LCL_Diff", "UCL_Diff")
rownames(CImat) <- rownames(Rresult$aov.tab)[2:5]
CImat[,1] <- SASresult[,"Lower"]
CImat[,3] <- SASresult[,"Upper"]
CImat[,2] <- RinfRes[2:5,"LCL"]
CImat[,4] <- RinfRes[2:5, "UCL"]
CImat[,5] <- CImat[,1] - CImat[,2]
CImat[,6] <- CImat[,3] - CImat[,4]
print(CImat)
cat("\n\n")
}
formatTFno <- function(x)
{
if(x < 10)
return(paste("00", x, sep=""))
else if(x < 100)
return(paste("0", x, sep=""))
else
return(x)
}
# Function serves as helper function to define input-parameters of 'generic.test.function' in
# separate environments.
get.test.function <- function(Data, prec=NULL)
{
inputData <- Data
precision <- prec
f <- function(){generic.test.function(Data=inputData, prec=precision)}
return(f)
}
if(realWorldModel1)
{
for(i in 1:nrow(by_PID_Lot))
{
fname <- paste("TF", formatTFno(noTF+i), ".PID_", by_PID_Lot[i, "PID"], "_Lot_", by_PID_Lot[i, "lot"], sep="")
tmp.data <- realData[which(realData$PID == by_PID_Lot[i, "PID"] & realData$lot == by_PID_Lot[i, "lot"]),]
assign(fname, get.test.function(Data=tmp.data, prec=TestPrecision))
}
noTF <- noTF + nrow(by_PID_Lot)
}
######### Model 2 for the real-world dataset
model2 <- y~lot/calibration/day/run
### note, "tc.path" defined in RunAllTests.R
SASrefModel2 <- read.delim(paste(tc.path, "SASresultsRealData_Model2_by_PID.txt", sep="/"), header=TRUE)
PIDs <- unique(as.character(realData$PID))
generic.test.function2 <- function(Data, prec=NULL)
{
PID <- Data$PID[1]
cat("\n>>> REAL-DATA MODEL 2: Check R VCA results v.s SAS PROC MIXED reference results for PID =",PID)
cat(" (tolerance-value:", prec, ")\n")
SASresult <- SASrefModel2[which(SASrefModel2$PID == PID),]
Rresult <- anovaVCA(model2, Data, NegVC=TRUE)
RinfRes <- VCAinference(Rresult, VarVC=TRUE, constrainCI=FALSE)$ConfInt$VC$TwoSided
nr <- nrow(Rresult$aov.tab)
# actually check SAS- and R-results
for(i in 2:nr)
{
checkEquals(signif(Rresult$aov.tab[i, "VC"], Nsignif(SASresult[i-1, "Estimate"])), SASresult[i-1, "Estimate"], # check equality of all VC-estimates
tolerance=prec)
if(i == 6) # also check CI of error-VC
{
checkEquals(signif(RinfRes[i, "LCL"], Nsignif(SASresult[i-1, "Lower"])), SASresult[i-1, "Lower"],
tolerance=prec)
checkEquals(signif(RinfRes[i, "UCL"], Nsignif(SASresult[i-1, "Upper"])), SASresult[i-1, "Upper"],
tolerance=prec)
}
}
cat("\n\nSAS PROC MIXED uses the inverse of the Fisher-Information Matrix as approximation of Covariance-Matrix of Variance Components.")
cat("\nThis is equal to the one obtained via ANOVA-approach stated in \"Variance Components\" (Searle et al. 1991) in case")
cat("\nof balanced designs, otherwise Var(VC) of both results may differ:\n\n")
CImat <- matrix(NA, ncol=6, nrow=5)
colnames(CImat) <- c("SAS_LCL", "R_LCL", "SAS_UCL", "R_UCL", "LCL_Diff", "UCL_Diff")
rownames(CImat) <- rownames(Rresult$aov.tab)[2:6]
CImat[,1] <- SASresult[,"Lower"]
CImat[,3] <- SASresult[,"Upper"]
CImat[,2] <- RinfRes[2:6,"LCL"]
CImat[,4] <- RinfRes[2:6, "UCL"]
CImat[,5] <- CImat[,1] - CImat[,2]
CImat[,6] <- CImat[,3] - CImat[,4]
print(CImat)
cat("\n\n")
}
# Function serves as helper function to define input-parameters of 'generic.test.function' in
# separate environments.
get.test.function2 <- function(Data, prec=NULL)
{
inputData <- Data
precision <- prec
f <- function(){generic.test.function2(Data=inputData, prec=precision)}
return(f)
}
if(realWorldModel2)
{
for(i in 1:length(PIDs))
{
fname <- paste("TF", formatTFno(noTF+i), ".Model2_PID_", PIDs[i], sep="")
tmp.data <- realData[which(realData$PID == PIDs[i]),]
assign(fname, get.test.function2(Data=tmp.data, prec=TestPrecision) )
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.