[R-sig-eco] Using NADA and rkt for seasonal Mann Kendall tests for censored datasets

clarkbar clark.tim.r at gmail.com
Thu Jul 24 16:59:14 CEST 2014


I have recently put together some code for running trend analyses on censored
datasets with shifting Method Detection Limits (MDLs). I have applied the
NADA package to determine the log mean and log standard deviation; these are
then used to generate log-normal random numbers which then replace the <MDL
observations. From this, I apply the rkt package for seasonal Mann-Kendall
trend test to determine. 
I know the NADA package has cenken, but that has limited covariate and
seasonal capabilities, and I believe my approach below is more conservative. 

I'm sorry if the code is sloppy, but I'm pretty new to all this.. going on
nearly 2 months now. 
I would really appreciate your feedback and ideas. I think my method is
similar to <a
href="http://dugi-doc.udg.edu/bitstream/handle/10256/708/Olea.pdf?sequence=1">Olea's,
but I could never get ILR to cooperate with me. 

Thanks in advance. 

#example data creation - probably not the best way to do this... 
test<-matrix(c(rep(1:7,each=20,1),rep(1:2,each=70), 
         rep(rlnorm(10,-5.6,.2),2), 
         rep(rlnorm(10,-5.6,.3)*1.2,2), 
         rep(rlnorm(10,-5.6,.3)*1.22,2), 
         rep(rlnorm(10,-5.6,.2)*1.25,2), 
         rep(rlnorm(10,-5.6,.3)*1.3,2), 
         rep(rlnorm(10,-5.6,.35)*1.4,2), 
         rep(rlnorm(10,-5.6,.35)*1.4,2)), 
         ncol=3) 
colnames(test)<-c('Year',"Season","Obs") 

test<-as.data.frame(test) 
with(test,rkt(Year,Obs,Season,correct=T,rep='a')) 
with(test,plot(Obs~Year)) 

#function below 
require("NADA") 
require("rkt") 
MDL_fix<-function(value,detection,year,block,CV,month,plot_title) 
  #Observed Value vector, Detection Limit Vector,Block Vector for seasonal
MannKendall,covariate,month,Plot title 
{ 
  YearMonth=year+month/12 
  #using NADA package, determine log-mean of and log-standard deviation of
the observed valued 
  #if(mean(value)<1) {#determine if log or -log should be used (cenfit has
issues with negatives) 
  #lmeanvalue<-{sum(summary(cenmle(value,value<detection))[[9]][1:2])} 
  #lsdvalue<-{summary(cenmle(value,value<detection))[[6]]} 
  #} 
  #if(mean(value)>=1) {#determine if log or -log should be used (cenfit has
issues with negatives) 
  if(length(which(value<detection))/length(value)>.50){ 
    return("ERROR: TOO MANY POINTS BELOW MDL")} 
  lmeanvalue<-{(median(cenfit((log(value)),value<detection))[[1]])} 
    lsdvalue<-{(sd(cenfit(log(value),value<detection)))[[1]]} 
  #} 
  if(length(which(value<detection))/length(value)>.05){ #only pursue MDL
fix if >5% of data censored, otherewise: do 1/2 MDL method 
    #create matrix to fill with Mann-Kendall Output 
    rkt_1<-matrix(1,runs,12) 
    colnames(rkt_1)<- c('2-sided
p-value','Score',"Slope","Var(Score)",'2-sided
p-value_corrected','Var(Score)_corrected', 
                        'Partial Score', 'Partial 2-sided p-value', "Partial
Var(Score)", "Partial 2-sided p-value_corrected" 
                        , 'Partial Var(Score)_corrected',"Tau") 
    for(i in seq(1:runs)) { 
{ 
  xj<-1:length(value) #create random number vector 
  MDL_fixed<-1:length(value) #create final value vector 
  for(j in seq(1:length(value))) { 
{ 
  if(value[j]<detection[j]) #only pursue number generation if the observed
value is below the detection limit 
{ 
    #create a random number (distributed log-normally based on lmean and
lsd) that is below the detection limit 
    repeat { 
      xj[j]<-rlnorm(1,lmeanvalue,lsdvalue) 
      if(xj[j]<detection[j]) {break} 
    } 
  } 
} 
    MDL_fixed[j]<-ifelse(value[j]<detection[j],xj[j],value[j])
#replace values below the detection limit with generated number 
  } 
} 
if(!missing(CV)& !missing(block)) { #if covariate and block present, do
seasonal mann-kendall 
rkt_1[i,]<-as.vector(unlist(rkt(year,MDL_fixed,block,CV,correct=T,rep="a")))
#run MK for each random number generation 
} 
if(missing(block) | missing(CV)){  #if covariate and block mising, do
mann-kendall 
 
rkt_1[i,]<-as.vector(unlist(rkt(year,MDL_fixed,correct=F,rep="a")))
#run MK for each random number generation 
} 
    } 
#plot final iteration of MDL_fixed 
plot(YearMonth,MDL_fixed,
log='y',main=as.character(substitute(plot_title)),xlab="Year",ylab='Concentration(ppm)') 
yaxis<-10^(par('usr')[c(3,4)]) #grab axis size 
#draw first quartile slope and intercept 
abline(a=median(value[which(value>detection)])-fivenum(rkt_1[,"Slope"])[2]*median(year[which(value>detection)]),b=fivenum(rkt_1[,"Slope"])[2],
untf=TRUE, col="red") 
#draw median slope and intercept 
abline(a=median(value[which(value>detection)])-fivenum(rkt_1[,"Slope"])[3]*median(year[which(value>detection)]),b=fivenum(rkt_1[,"Slope"])[3],
untf=TRUE, col="blue") 
#draw third quartile slope and intercept 
abline(a=median(value[which(value>detection)])-fivenum(rkt_1[,"Slope"])[4]*median(year[which(value>detection)]),b=fivenum(rkt_1[,"Slope"])[4],
untf=TRUE, col="green") 
par(new=T) #hold on 
#plot detection limit 
plot(YearMonth,detection, ylim=yaxis,
log='y',type='l',axes=F,xlab='',ylab='',lty=3) 
par(new=F) #hold off 
return(rkt_1) #return matrix of iterations 
  } 
else{ 
  value_half_MDL<-ifelse(value>detection,value,0.5*detection) 
  if(!missing(CV)& !missing(block)) {#if covariate and block present, do
seasonal mann-kendall 
 
rkt_noMDL=as.vector(unlist(rkt(year,value_half_MDL,block,CV,correct=T,rep="a")))#run
MK w/o num geneartion 
  } 
  if(missing(CV)| missing(block)) {#if covariate and block mising, do
mann-kendall 
   
rkt_noMDL=as.vector(unlist(rkt(year,value_half_MDL,correct=F,rep="a")))#run
MK w/o num geneartion 
  } 
  #plot value over time 
  plot(YearMonth,value_half_MDL,
log='y',main=as.character(substitute(plot_title)),xlab="Year",ylab='Concentration(ppm)') 
  yaxis<-10^(par('usr')[c(3,4)])#grab axis size 
  par(new=T) 
  plot(YearMonth,detection, ylim=yaxis,
log='y',type='l',axes=F,xlab='',ylab='',lty=3) 
  par(new=F) 
 
abline(a=median(value[which(value>detection)])-rkt_noMDL[3]*median(year[which(value>detection)]),b=rkt_noMDL[3],
untf=TRUE, col="red") 
  
  return(rkt_noMDL) #return vector of Mann Kendall 
} 
} ##MDL fixing code for log-normal 

runs=100 
summary(with(test,MDL_fix(Obs,detection=c(rep(.005,80),rep(.002,60)),Year,Season,,month=rep(12,140)),"hello"))



--
View this message in context: http://r-sig-ecology.471788.n2.nabble.com/Using-NADA-and-rkt-for-seasonal-Mann-Kendall-tests-for-censored-datasets-tp7578989.html
Sent from the r-sig-ecology mailing list archive at Nabble.com.



More information about the R-sig-ecology mailing list