vignettes/articles/censored_value.Rmd
censored_value.Rmd
Dans ce document, on retrouve les fonctions que nous avons créé pour imputer des valeurs avec des données censurées de contaminants d’ECCC.
Les packages nécessaires sont:
La première fonction, censor() accepte des jeux de données qui contiennent des valeurs censurées (càd des données sous la limite de détection/quantification) formatées comme-ci: “<0.001”. Les premières colonnes dans le jeu de données doivent être celles que nous ne voulons pas “dé-censurer”, donc des colonnes non-numériques (ex. FID, Location, Sex) et les colonnes numériques que nous ne souhaitons pas dé-censurer (ex. Year, isotopes stables, mesures morphométriques).
La fonction analysera chaque colonne individuellement à partir de la colonne de départ préalablement spécifiée. Par la suite, une nouvelle colonne, nommée avec le nom du composé et le suffixe “cen” sera ensuite créée et contiendra un indicateur binaire TRUE ou FALSE. Si une observation du composé contient un “<”, c’est-à-dire que c’est une valeur censurée, l’observation dans la nouvelle colonne (l’indicateur de censure) sera “TRUE”. Si l’observation n’est pas censurée, l’indicateur sera “FALSE”. Ceci nous permettra d’utiliser des packages R développés pour des valeurs censurées. Enfin, la fonction censor() retirera les symboles “<” du jeu de données et numérisera toutes les colonnes contenant des données de contaminants. À ce stade, le jeu de données contiendra des vraies concentrations de contaminants (“FALSE” dans la colonne indicatrice du composé) et des limites de détection (“TRUE” dans les colonnes indicatrices).
Pour utiliser la fonction, il suffit de faire rouler les lignes suivantes:
censor(data, t)
#For example
OCcen <- censor(OC, 8)
t dénote le numéro de la colonne à laquelle nous voulons commencer le processus de “dé-censuration”.
censor <- function(data, t) {
cols <- colnames(data) #create a vector of col names for future naming ease
for (i in t:ncol(data)) { #t = number of the col we start at
#(skip the sample info, start at first compound)
#if "<" is found, put TRUE in the new col because it is a non-detect,
#if not, put FALSE (= uncensored value)
data$new <- if_else(grepl( "<", data[, (i)]), TRUE, FALSE)
#paste the compound name to the col head followed by "cen"
names(data)[names(data) == 'new'] <- paste0(cols[[i]], "cen")
#if "<" is found, remove it for easy numeric conversion
data[, (i)] <- str_replace(data[, (i)], "<", "")
#convert to numeric
data[, (i)] <- as.numeric(as.character(data[, (i)]))
}
return(data)
}
Une fois le jeu de donné “dé-censuré”, les valeurs pour les observations qui étaient sous la limite de détection peuvent être imputées.
L’input doit contenir ces colonnes: “FID”, “Year”, “d15N”, “d13C”, et “Lipid”. Si une ou plusieurs de ces colonnes ne sont pas présentes dans le jeu de données, il vous faut simplement ajouter une colonne vide avec le nom approprié. Note:* En plus des colonnes mentionnées précédemment nous pouvons inclure d’autres facteurs (colonnes) pour lesquels les valeurs de doivent pas être dé-censurées. Pour ce fait, simplement ajouter le nom du facteur dans les lignes de code ci-dessous où #COVARIATES est inscrit.
*Dans le cas de données historiques, nous devons corriger le d13C pour l’effet Suess. On peut changer le nom dans la fonction en remplaçant le d13C (d13c -> d13CS).
Note: La fonction ci-dessous inclut Year et Location - c’est-à-dire que les observations seront regroupées par Année et par Site pour permettre ensuite l’imputation des valeurs censurées. Toutefois, si seulement un de ces facteurs est nécessaire, il suffit de retirer le second du script (#dénoté par 3 étoiles à la fin de la ligne de script).
Tout d’abord, la fonction séparera les valeurs qui ne doivent pas être imputées (ex. d15N, d13CS, Lipid, etc.). Ces colonnes seront rajoutées à l’output final. Ensuite, le jeu de données sera groupé puis séparé par Année et par Site. La première loop sélectionne et isole chaque combinaison Année-Site individuellement pour que faciliter l’imputation des valeurs le plus simplement possible. La deuxième loop* (qui se trouve à l’intérieur de la première) sélectionne les composés un par un et isole la colonne contenant les données (réelles et censurées), ainsi que la colonne avec l’indicateur de censure correspondant. Important: deux lignes de code très importantes empêche de briser la loop: 1. si toutes les valeurs pour un composé dans l’Année et le Site isolé sont “NA”, la fonction passera directement au prochain composé. 2. si trop de valeurs sont des limites de détection (“TRUE” dans la colonne indicatrice), les valeurs ne peuvent pas être imputées car pas assez de vraies données présentes et par conséquent la fonction passera directement au prochain composé.
*La deuxième loop utilise l’argument h, qui dénote le numéro de la colonne du premier composé (contaminant). Par exemple, h = 4 si Site et Année sont inclus, mais h = 3 si seulement un de ses deux facteurs est inclus, puisque le jeu de données entrant dans la deuxième loop sera formaté comme tel : “FID”, “Year”, “Location”, “Composé 1”, etc.
La fonction cenros() du package NADA sera utiliser pour calculer des moyennes en tenant compte des valeurs censurées, et permet d’interpoler des valeurs fictives afin d’obtenir ces moyennes. Cette fonction se base sur la méthode statistique “régression d’ordre statistique” (ROS) permettant d’assigner des valeurs interpolées aux valeurs censurées présentes dans le jeu de données. Le processus est répété pour chaque composé à l’intérieur d’une Année et d’un Site, et également pour chaque combinaison de groupes Année-Site. Les résultats seront ajoutés à un dataframe vide (Format : long). Lorsque les deux loops complétées, le dataframe sera transposé en format wide.
Pour l’instant j’ai retiré cette opération pour que des NAs restent: puis on remplace les NA restants (ceux qui ont été sauté à cause de trop de non-detects) avec une valeur égale à la moitié de la limite de détection, provenant d’un fichier LOD qui est inclut dans le input de la fonction. Le fichier LOD doit contenir une ligne par échantillon, avec la limite de détection pour chaque composé à chaque année. #
La fonction impute() est utilisée comme-ci:
impute(data, h)
#For example
OCint <- impute(OCcen, 9)
impute <- function(data, h) { #h is column the second loop starts at. D
#etermined by what you are including
#In only year and FID, h = 3, if Year and location, h = 4
SI<-subset(data, select=c(FID, Year, Location, d15N, d13C, d34S, Lipid))
#*COVARIATES*
#to merge with our interpolated data set later
dat2 <- subset(data, select = -c(d15N, d13C, d34S, Lipid)) #*COVARIATES*
#only keep year, location, FID, and compound values and censor indicators
cols <- colnames(dat2)
colony <- dat2 %>% group_by(Location, Year) %>% group_split(dat2)
stats <- data.frame(FID = as.character(),
Location = as.character(),
Year = as.numeric(),
Compound = as.character(),
Concentration = as.numeric()) #make empty dataframe - long
for (i in 1:length(colony)) { #start with the group in list
#i=1 #troubleshooting
loc <- colony[[i]] #isolate group year for coding simplicity
k<-ifelse(ncol(loc) %% 2 == 0,round((ncol(loc))/2), round((ncol(loc))/2)+1)
#calculates the halfway mark of the df,
#i.e. where the compounds stop and censure indicators start
for (f in h:k) { #start at first compound: 3rd col
#f=4 #troubleshooting
#isolate so we only have compound values and indicators
x <- grep(cols[f], colnames(loc), value = FALSE) #find censor indicator
comp <- as.data.frame(loc[, c(1, x)]) #isolate the compound and cen
colnames(comp) <- c("FID", "Compound", "Cen")
comp2 <- comp[order(comp$Compound, decreasing = FALSE, na.last = FALSE),]
d <- nrow(loc) #how many obs do we have in this group
e <- d-1
if(d < 2) {print(loc$FID)} #Tells us which are singular in their group
#(ex. single sample in that year/location)
if(is.na(sum(comp[, 2])) == TRUE) next #If all vals are ND, skip
if(length(grep("TRUE", comp2[,3])) >= e) next #If all vals are ND, skip
#convert to ROS object
compros <- cenros(comp2[, 2], comp2[, 3])
#We want to keep each ind value so we can pool them properly later
add <- data.frame(FID = comp2$FID, #add IDs
Location = loc$Location, #add all the years
Year = loc$Year,
Compound = rep(cols[f], times = d), #Compound name
Concentration = dput(as.numeric(compros$modeled)))
stats <- rbind(stats, add) #append new rows
}
}
interp <- stats %>%
group_by(Location, Year, Compound) %>%
pivot_wider(id_cols = c(FID, Location, Year),
names_from = Compound, values_from = Concentration)
#Here we are filling the remaining NAs (caused by non-detects)
#with LOD/2 values so we don't have empty data
#patched <- rows_patch(interp, LOD, by = "FID")
final <- merge(SI, interp, by = c("FID", "Location", "Year"))
#patched instead of interp if patching
}
Dans la fonction impute(), une commande indique si un échantillon est seul dans son groupe Année-Site (impute l’exclu par défaut). Nous ne pouvons pas utiliser les méthode de non-detects (ROS) sur un seul échantillon et la fonction impute() exclu l’échantillon seul par défaut. Cette ligne de code demande à R d’imprimer le FID de l’échantillon si tel est le cas. Il est donc important de vérifier le output de impute() dans la console si des FID ont été imprimés. En les isolants (voir exemple plus bas), nous pouvons passer les échantillons “seuls” dans la fonction singles(). Singles() est adaptée de la fonction impute() afin de rapporter les valeurs non-censurées, et de remplacer les limites de détection par NA. Singles() prend le même argument h que impute().
singles(data, h)
#for example
ocextra <- singles(OCcen, 9)
singles <- function(data, h) { #h is column the second loop starts at.
#In only year and FID, h = 3, if Year and location, h = 4
SI <-subset(data, select=c(FID, Year, Location, d15N, d13C, d34S, Lipid))
#*COVARIATES* above
#to merge with our interpolated data set later
dat2 <- subset(data, select = -c(d15N, d13C, d34S, Lipid)) #*COVARIATES*
#only keep year, location, FID, and compound values and censor indicators
cols <- colnames(dat2)
colony <- dat2 %>% group_by(Location, Year) %>% group_split(dat2)
stats <- data.frame(FID = as.character(),
Location = as.character(),
Year = as.numeric(),
Compound = as.character(),
Concentration = as.numeric()) #make empty dataframe
for (i in 1:length(colony)) { #start with the first group in list
#i=2 #troubleshooting
loc <- colony[[i]] #isolate group location for coding simplicity
k<-ifelse(ncol(loc) %% 2 == 0,round((ncol(loc))/2), round((ncol(loc))/2)+1)
for (f in h:k) { #start at first compound: 3rd col
#f=4 #troubleshooting
#isolate so we only have compound values and indicators
x <- grep(cols[f], colnames(loc), value = FALSE) #find censor indicator
comp <- as.data.frame(loc[, c(1, x)]) #isolate the compound and censor ind
colnames(comp) <- c("FID", "Compound", "Cen")
#for singles we only keep values if their censure indicator is FALSE
add <- data.frame(FID = comp$FID, #add IDs
Location = loc$Location, #add all the years
Year = loc$Year,
Compound = cols[f], #paste in the Compound name
Concentration = ifelse(comp$Cen == "FALSE",
comp$Compound, NA))
#If value is uncensored (FALSE), put the compound data, if censured put NA
stats <- rbind(stats, add) #append new rows
}
}
interp <- stats %>%
group_by(Location, Compound) %>%
pivot_wider(id_cols = c(FID, Year, Location),
names_from = Compound, values_from = Concentration)
#Here we are filling the remaining NAs (caused by non-detects)
#with LOD/2 values so we don't have empty data
#patched <- rows_patch(interp, LOD, by = "FID")
final <- merge(SI, interp, by = c("FID", "Location", "Year"))
#patched instead of interp if patching
} #Essentially impute() for locations with single observations
#(i.e. imputing NDs is impossible so we exculde censured data and keep real values)
L’exemple suivant montre comment identifier des échantillons seuls et les rajouter dans le output de impute():
pcbex <- PCBcen[PCBcen$FID == "W222559-01"| PCBcen$FID == "W221979-02", ]
#find x or y that were printed by impute
pcbex1 <- singles(pcbex, 4)
Append to impute output
PCBint <- dplyr::bind_rows(PCBint, pcbex1) #Bind the two dataframes
#but keep columns even if there aren't in both dfs
PCBint <- PCBint[,colSums(is.na(PCBint)) < nrow(PCBint)]
#remove columns composed only of NAs
Pour calculer les sommes de différentes familles de composés, la méthode Kaplan Meier (KM) est utilisée pour calculer des moyennes en tenant compte de plusieurs valeurs censurées différentes. La moyenne est la somme divisée par le nombre d’observations :
moyenne = somme des observations / nombre d'observations
ainsi la somme peut être facilement déduite en ce basant sur l’équation de la moyenne:
Somme = moyenne * nombre d'observations
Par conséquent, la moyenne estimée à l’aide de la méthode KM multipliée par le nombre d’observations (dans ce cas le nombre de composé) permet d’obtenir la somme estimée.
Malheureusement, il est difficile de construire une fonction pour calculer les sommes puisque les familles diffèrent par groupe de contaminants (OC, PCB, BFR). Ainsi, la loop développées ci-dessous devra être modifiée pour chaque groupe séparemment (et ce même dans chaque script dépendant des données).
Il est important de noter que les sommes décrites dans les loops ci-bas ne sont que des exemples des sommes que nous pouvons calculer. Les loops peuvent être modifier pour satisfaire vos besoins en ajoutat ou en retirant des sommes ou des composés.
Pour les OC:
OCsums <- data.frame(FID = as.character(),
Sum14OC = as.numeric(),
SumDDT = as.numeric(),
SumCHL = as.numeric(),
SumHCH = as.numeric())
#
for (i in 1:nrow(OCcen)) { #cycles through the individual samples
#i=48 #troubleshooting
ind <- OCcen[i,]
indconc <- ind %>% pivot_longer(cols = 6:19,
names_to = "Compound", values_to = "Concentration") %>%
select(c("FID", "Year","Compound", "Concentration"))
indcen <- ind %>%pivot_longer(cols = 20:33,
names_to = "Compound", values_to = "Cen") %>%
select(c("FID", "Year","Compound", "Cen"))
indcen$Compound <- str_replace(indcen$Compound, "cen", "")
indlong <- merge(indconc, indcen, by = c("FID", "Year", "Compound"))
print(indlong$FID) #see where errors are occuring
#First all 14 OCs
U <- indlong$Concentration
V <- indlong$Cen
indfit <- with(indlong, censtats(U, V)) #need to be vectors
num <- nrow(indlong)
sum14 <- (indfit[1,2])*num
#Now DDT compounds
ddt <- subset(indlong, Compound == "ppDDD" | Compound == "ppDDE" |
Compound == "ppDDT") #If we are missing one of these from OCint,
#it is a good indicator we'll be missing it here so remove it from the list, and
#reduce the number in the if statement by the number of compounds removed
if(length(grep("TRUE", ddt[,5])) >= 3) {print(indlong$FID)}
if(length(grep("TRUE", ddt[,5])) >= 3) next #If all vals are ND, skip to next
ddtc <- ddt$Concentration
ddtcen <- ddt$Cen
ddtfit <- with(ddt, censtats(ddtc, ddtcen))
DDT <- (ddtfit[1,2])* 3 #multiply estimated mean by # compounds
#SumCHL
chl <- subset(indlong, Compound == "OxyChlordane" | Compound == "cChlordane"
| Compound == "tChlordane" | Compound == "cNonachlor")
if(length(grep("TRUE", chl[,5])) >= 4) {print(indlong$FID)}
if(length(grep("TRUE", chl[,5])) >= 4) next #If all vals are ND, skip to next
chlc <- chl$Concentration
chlcen <- chl$Cen
chlfit <- with(chl, censtats(chlc, chlcen))
CHL <- (chlfit[1,2])* 4 #multiply estimated mean by # compounds
#SumHCH
hch <- subset(indlong, Compound == "aHCH" | Compound == "bHCH" |
Compound == "gHCH")
if(length(grep("TRUE", hch[,5])) >= 3) next #If all vals are ND, skip
hchc <- hch$Concentration
hchcen <- hch$Cen
hchfit <- with(hch, censtats(hchc, hchcen))
HCH <- (hchfit[1,2])* 3 #multiply estimated mean by # compounds
add <- data.frame(FID = ind$FID,
Sum14OC = sum14,
SumDDT = DDT,
SumCHL = CHL,
SumHCH = HCH)
OCsums <- rbind(OCsums, add)
}
Pour les PCB: (Important: Faire attention aux espaces dans les noms des composés)
PCBsums <- data.frame(FID = as.character(),
SumPCB = as.numeric(),
SumTetra = as.numeric(),
SumPenta = as.numeric(),
SumHexa = as.numeric(),
SumHepta = as.numeric(),
SumOcta = as.numeric(),
SumOrtho = as.numeric(),
Sum6 = as.numeric())
#
for (i in 1:nrow(PCBcen)) { #cycles through the individual samples
#i= 24 #troubleshooting
ind <- PCBcen[i,]
indconc <- ind %>% pivot_longer(cols = 9:43,
names_to = "Compound", values_to = "Concentration") %>%
select(c("FID", "Year","Compound", "Concentration"))
indcen <- ind %>%pivot_longer(cols = 44:78,
names_to = "Compound", values_to = "Cen") %>%
select(c("FID", "Year","Compound", "Cen"))
indcen$Compound <- str_replace(indcen$Compound, "cen", "")
indlong <- merge(indconc, indcen, by = c("FID", "Year", "Compound"))
print(indlong$FID) #see where errors are occuring
#First all PCBs
U <- indlong$Concentration
V <- indlong$Cen
indfit <- with(indlong, censtats(U, V)) #need to be vectors
num <- nrow(indlong)
sumPCB <- (indfit[1,2])*num
#Tetra
tetra <- subset(indlong, Compound == "PCB52" | Compound == "PCB49" |
Compound == "PCB44" | Compound == "PCB70")
if(length(grep("TRUE", tetra[,5])) >= 4) {print(indlong$FID)}
if(length(grep("TRUE", tetra[,5])) >= 4) next #If all vals are ND, skip
tetrac <- tetra$Concentration
tetracen <- tetra$Cen
tetrafit <- with(tetra, censtats(tetrac, tetracen))
TETRA <- (tetrafit[1,2])* nrow(tetra) #multiply mean by # compounds
#Penta
penta <- subset(indlong, Compound == "PCB87" | Compound == "PCB99" |
Compound == "PCB101" | Compound == "PCB105" |
Compound == "PCB110" | Compound == "PCB118")
pentac <- penta$Concentration
pentacen <- penta$Cen
pentafit <- with(penta, censtats(pentac, pentacen))
PENTA <- (pentafit[1,2])* nrow(penta)
#Hexa
hexa <- subset(indlong, Compound == "PCB128" | Compound == "PCB138" |
Compound == "PCB151" | Compound == "PCB153" |
Compound == "PCB158")
hexac <- hexa$Concentration
hexacen <- hexa$Cen
hexafit <- with(hexa, censtats(hexac, hexacen))
HEXA <- (hexafit[1,2])* nrow(hexa)
#Hepta
hepta <- subset(indlong, Compound == "PCB170" | Compound == "PCB171" |
Compound == "PCB180" | Compound == "PCB183" |
Compound == "PCB187")
heptac <- hepta$Concentration
heptacen <- hepta$Cen
heptafit <- with(hepta, censtats(heptac, heptacen))
HEPTA <- (heptafit[1,2])* nrow(hepta)
#Octa
octa <- subset(indlong, Compound == "PCB194" | Compound == "PCB195")
if(length(grep("TRUE", octa[,5])) >= 2) {print(indlong$FID)}
if(length(grep("TRUE", octa[,5])) >= 2) next #If all vals are ND, next
octac <- octa$Concentration
octacen <- octa$Cen
octafit <- with(octa, censtats(octac, octacen))
OCTA <- (octafit[1,2])* nrow(octa)
#Ortho
ortho <- subset(indlong, Compound == "PCB70" | Compound == "PCB105" |
Compound == "PCB118")
orthoc <- ortho$Concentration
orthocen <- ortho$Cen
orthofit <- with(ortho, censtats(orthoc, orthocen))
ORTHO <- (orthofit[1,2])* nrow(ortho)
#Sum of 6
six <- subset(indlong, Compound == "PCB31/28" | Compound == "PCB101" |
Compound == "PCB138" | Compound == "PCB153" |
Compound == "PCB180")
sixc <- six$Concentration
sixcen <- six$Cen
sixfit <- with(six, censtats(sixc, sixcen))
SIX <- (sixfit[1,2])* nrow(six)
add <- data.frame(FID = ind$FID,
SumPCB = sumPCB,
SumTetra = TETRA,
SumPenta = PENTA,
SumHexa = HEXA,
SumHepta = HEPTA,
SumOcta = OCTA,
SumOrtho = ORTHO,
Sum6 = SIX)
PCBsums <- rbind(PCBsums, add)
}
Pour les BFR
BFRsums <- data.frame(FID = as.character(),
SumPBDE = as.numeric(),
SumPentaBDE = as.numeric(),
SumOctaBDE = as.numeric(),
SumDecaBDE = as.numeric())
#
for (i in 1:nrow(BFRcen)) { #cycles through the individual samples
#i=7 #troubleshooting
ind <- BFRcen[i,]
indconc <- ind %>% pivot_longer(cols = 9:31, names_to = "Compound", values_to = "Concentration") %>%
select(c("FID", "Year","Compound", "Concentration"))
indcen <- ind %>%pivot_longer(cols = 32:52, names_to = "Compound", values_to = "Cen") %>%
select(c("FID", "Year","Compound", "Cen"))
indcen$Compound <- str_replace(indcen$Compound, "cen", "")
indlong <- merge(indconc, indcen, by = c("FID", "Year", "Compound"))
indlong <- na.omit(indlong)
#print(indlong$FID) #see where errors are occuring
#First all 14 OCs
U <- indlong$Concentration
V <- indlong$Cen
indfit <- with(indlong, censtats(U, V)) #need to be vectors
num <- nrow(indlong)
sumpbde <- (indfit[1,2])*num
#
#Penta-BDEs
pentabde <- subset(indlong, Compound == "BDE47" | Compound == "BDE99" | Compound == "BDE100"
| Compound == "BDE153" | Compound == "BDE154/BB153" | Compound == "BDE85")
pentabdec <- pentabde$Concentration
pentabdecen <- pentabde$Cen
pentabdefit <- with(pentabde, censtats(pentabdec, pentabdecen))
PentaBDE <- (pentabdefit[1,2])* nrow(pentabde)
#Octa-BDEs
octabde <- subset(indlong, Compound == "BDE183" | Compound == "BDE209")
octabdec <- octabde$Concentration
octabdecen <- octabde$Cen
octabdefit <- with(octabde, censtats(octabdec, octabdecen))
OctaBDE <- (octabdefit[1,2])* nrow(octabde)
#Deca is only 209 so we'll add in manually
decabde <- subset(indlong, Compound == "BDE209")
decabdec <- decabde$Concentration
decabdecen <- decabde$Cen
add <- data.frame(FID = ind$FID,
SumPBDE = sumpbde,
SumPentaBDE = PentaBDE,
SumOctaBDE = OctaBDE,
SumDecaBDE = ifelse(decabdecen == "FALSE", print(decabdec), NA))
BFRsums <- rbind(BFRsums, add)
}
Plusieurs lignes du script sont importantes car elles empêchent la loop de briser (“fail safes”): 1. si tous les composés d’une famille ont des valeurs censurées pour un échantillon, la moyenne ne peut pas être estimée alors la loop passera automatiquement au prochain échantillon. Si la loop saute un échantillon, le FID sera imprimé dans le output dans la console. Alors comme pour impute(), il est important de vérifier dans la console les échantillons qui ont été sautés et de les traiter manuellement. Pour ce faire, rouler la loop pour un échantillon spécifique en roulant i = X (X = numéro de la rangée de l’échantillon), et noter les valeurs des sommes dans un autre dataframe)
Exemple: les NAs représentent les sommes qui n’ont pas pu être calculés pour 4 échantillons.
PCBpatch <- data.frame(FID = c("W223432-04", "W232539-01",
"W232539-02", "W232539-03"),
SumPCB = c(0.3936, 0.1833, 0.0868, 0.1481),
SumTetra = c(NA, 0.0068, 0.004, 0.0083),
SumPenta = c(0.0609, 0.0433, 0.0144, 0.0388),
SumHexa = c(0.196, 0.0666, 0.0278, 0.0522),
SumHepta = c(0.0872, 0.0424, 0.0251, 0.0318),
SumOcta = c(0.0087, NA, NA, NA),
SumOrtho = c(0.0449, 0.0247, 0.0082, 0.0207),
Sum6 = c(0.2136, 0.0805, 0.0365, 0.0655))
PCBsums <- rbind(PCBsums, PCBpatch)
Dépendant des jeux de données, il faudra ajouter les lignes de script comme “fail safes” (voir plus haut) à d’autres familles de contaminants. Vous pouvez toujours le rajouter à toutes les sommes si c’est plus facile que d’identifier la famille qui pose problème, mais bien faire attention de changer le df auquel il se réfère:
if(length(grep("TRUE", tetra[,5])) >= 4) {print(indlong$FID)}
#tetra is the df that needs to be changed for each sum
if(length(grep("TRUE", tetra[,5])) >= 4) next
#tetra is the df that needs to be changed for each sum
Une fois que tout roule bien, on joint le output de impute() (ex. OCint) à l’output des sommes (ex. OCsums).
OC <- merge(OCint, OCsums, by = "FID")
Voilà! Les valeurs censurées sont gérées et prêtes pour les tests statistiques :)