This report is automatically generated with the R
package knitr
(version 1.40
)
.
source("R Functions/functions_QA data.R") ### NOTE FOR COMPILATION feb/march 2019: # Look at column 'QACODE' in ceden formatted spreadsheet to see the Quality Control samples that need to be addressed - need data from them. (~206 samples in scope, most in cache creek or yuba below dam) #most QC samples appear bundled, with all the samples collected all being labeled QC (e.g. 4 samples (2 each total or dissolved) on same day/time/place # some QC samples don't appear to match with any other samples #samples that have mean or MPN listed in 'StatisticalBaseCode' are represented with AVG or E (for estimated) listed in the ResultQualCode # 286 water/sed samples in scope = mean per 'StatisticalBaseCode', 9 MPN (assume= 'most probable number') in 'StatisticalBaseCode' column - most are for 'suspended mercury' results and all are in cache creek #ceden samples not filtered out - use as confirmation of duplicate removal #we made when RL/MDL is -99 == blank because no info is gained from this ###if load more data in future: #check 'ActivityMediaSubdivisionName' column for 'suspended' #(most of the 'suspended' samples are described in the 'ResultSampleFractionText' column, and that is how we pulled them from this script) #the 4 samples listed as 'suspended' in 'ActivityMediaSubdivisionName' are currently all listed as 'sediment' in the ActivityMediaSubdivisionName column #however, those 4 are not in the current rivers/delta scope so they are not discussed int he script to pull out those samples as 'suspended' b/c they will be filtered out with GIS #we manually filtered the only monitoring location in the current delta/rivers scope that had additional result detection info (MDL, RL info) #this was for sample 'NARS_WQX-NOAA 1-2', which was the only monitoring location in our scope that had more than one entry in the 'resdetectqntlmt' tab #if future data pulls occur, check to see if any new data has a repeat entry in the 'resdetectqntlmt' tab and if so, if it is in our scope, then filter for that location as well. ##if in the future we do an additional data run, may need to do additional recoding if there is a result pasted above that includes results for both 'StatisticBaseCode' and 'ResultQualCode' #(e.g. if ND, mean is pasted, these individually won't be recoded because they will be seen as a string of different characters) ###MISC: #jf did DWR research to figure out result (0) = DNQ - see notes in that section below # mercury suspended is its own category - the material left on the filter after dissolving. suspended samples are described in the # and 'ResultSampleFractionText' column which was remaned as 'anaylte 2' and combined with mercruy/methylmercury for the complete analyte name # and 'suspended' samples were listed as well in the 'ActivityMediaSubdivisionName' column, but are out of the current scope so have not been pulled. #there were 4 samples in our scope that appeared to be mislabeled that we changed in R # and 'ResultSampleFractionText' was labeled 'bed sediment' but listed as 'water' in the 'ActivityMediaName' (matrix) #and as surface water in the 'ActivityMediaSubdivisionName'; so we changed it in R to 'sediment' in the 'ActivityMediaName' #and 'bottom material' in the 'ActivityMediaSubdivisionName' column; the fact it was a sediment sample was corroborated by the units and #the 'ResultAnalyticalMethod/MethodName' column entries #JF added a column for 'scope', copying what was done in WQP fish, to say if a sample is in the delta/rivers scope based on the GIS search ### LOAD DATA ### WQP <- readxl::read_excel('Reeval_Impl_Goals_Linkage_Analysis/Data/Aqueous/WQP_aq_sed.xlsx', sheet='Result(5) working data', guess_max = 30000) #adding 'guess_max' to this function would fix the column identification issues when loading the excel spreadsheet and prevent the need to prefilter the excel sheet nrow(WQP) #number of rows
## [1] 28168
### SELECT USED COLUMNS, ADD USER DEFINED COLUMNS, & RENAME COLUMNS TO CEDEN STANDARDS ### keep_cols <- c('SourceID','SourceRow', 'ProjectName','MonitoringLocationName','MonitoringLocationIdentifier','ActivityStartDate', 'ActivityStartTime/Time', 'ActivityMediaName','MonitoringLocationTypeName', 'CharacteristicName','ResultSampleFractionText','ResultMeasure/MeasureUnitCode', 'ResultMeasureValue','DetectionQuantitationLimitMeasure/MeasureValue','ResultDetectionConditionText', 'ResultLaboratoryCommentText','LatitudeMeasure','LongitudeMeasure','HorizontalCoordinateReferenceSystemDatumName') temp_cols <- c('OrganizationIdentifier', 'DetectionQuantitationLimitTypeName', 'DetectionQuantitationLimitMeasure/MeasureUnitCode', 'ActivityMediaSubdivisionName', 'MethodDescriptionText', 'ResultAnalyticalMethod/MethodIdentifier', 'ResultWeightBasisText', 'HydrologicEvent', 'HydrologicCondition', 'ResultParticleSizeBasisText', 'ResultCommentText', 'MeasureQualifierCode', 'ActivityCommentText', 'ActivityTypeCode', 'StatisticalBaseCode', 'ResultAnalyticalMethod/MethodName', 'ResultValueTypeName', 'ActivityMediaSubdivisionName') WQP_new <- WQP %>% select( c(keep_cols,temp_cols) ) %>% #filter( OrganizationIdentifier %are not% c('CEDEN') ) %>% #Remove this data since it is in CEDEN #filter(ActivityTypeCode != 'Quality Control Sample')%>% #filter(ActivityTypeCode %are not% c('Quality Control Sample')%>% rename( Unit = `ResultMeasure/MeasureUnitCode`, 'Project' = 'ProjectName', 'StationName' = 'MonitoringLocationName', 'StationCode' = 'MonitoringLocationIdentifier', 'SampleDate' = 'ActivityStartDate', 'SampleTime' = 'ActivityStartTime/Time', 'MatrixName' = 'ActivityMediaName', 'Analyte' = 'CharacteristicName', 'Analyte_part2' = 'ResultSampleFractionText', 'Result' = 'ResultMeasureValue', 'MDL' = 'DetectionQuantitationLimitMeasure/MeasureValue', 'TargetLatitude' = 'LatitudeMeasure', 'TargetLongitude' = 'LongitudeMeasure', 'CoordSystem' = 'HorizontalCoordinateReferenceSystemDatumName', 'ResultsComments' = 'ResultLaboratoryCommentText', 'ResultQualCode' = 'ResultDetectionConditionText', 'WBT' = 'MonitoringLocationTypeName' )%>% mutate( #Add user defined columns CitationCode = 'WQP_2018', LabBatch = NA_character_, LabSampleID = NA_character_, BatchVerification = NA_character_, ComplianceCode = NA_character_, BatchComments = NA_character_, SampleID = NA_character_, #ResultQualCode = paste(ResultQualCode, StatisticalBaseCode, sep= ', '), QACode = paste(ActivityTypeCode, paste0('QA Code: ', MeasureQualifierCode), sep=' ~ '), ActivityMediaSubdivisionName = ifelse(Analyte_part2 == 'Bed Sediment' & ActivityMediaSubdivisionName == 'Surface Water', 'Bottom material', ActivityMediaSubdivisionName), SampleTypeCode = paste(paste0('Result value: ', ResultValueTypeName), paste0('Sample Type: ', ActivityMediaSubdivisionName), sep=' ~ '), CollectionComments = paste(paste0('Particle Size: ',ResultParticleSizeBasisText), ResultCommentText, ActivityCommentText, sep=' ~ '), SampleComments = paste(paste0('HydrologicalEvent: ', HydrologicEvent), paste0('HydrologicCondition: ', HydrologicCondition), sep=' ~ '), MethodName = paste(`ResultAnalyticalMethod/MethodName`, `ResultAnalyticalMethod/MethodIdentifier`, MethodDescriptionText, sep = '~') ) nrow(WQP_new)
## [1] 28168
#View(WQP_new) ### FORMAT COLUMN PARAMETERS ### # Standardize MatrixName Groups # unique(WQP_new$MatrixName)
## [1] "Water" "Sediment" "Soil"
WQP_new <- WQP_new %>% mutate( MatrixName = recode(MatrixName, 'Water' = 'Aqueous') ) #[1] "Water" "Sediment" "Soil" - no changes necessary (soil will be filtered out) # Standardize WTB (WaterBodyType) Groups # unique(WQP_new$WBT)
## [1] "Stream" "Stream: Canal" ## [3] "Stream: Ditch" "Spring" ## [5] "Estuary" "Wetland" ## [7] "River/Stream" "Other-Surface Water" ## [9] "River/Stream Perennial" "River/Stream Intermittent" ## [11] "River/stream Effluent-Dominated" "Channelized Stream" ## [13] "Wetland Palustrine-Shrub-Scrub"
unique(paste(WQP_new$MatrixName, WQP_new$WBT, sep='; '))
## [1] "Aqueous; Stream" "Aqueous; Stream: Canal" ## [3] "Aqueous; Stream: Ditch" "Sediment; Stream" ## [5] "Aqueous; Spring" "Aqueous; Estuary" ## [7] "Soil; Stream" "Sediment; Estuary" ## [9] "Aqueous; Wetland" "Sediment; Stream: Canal" ## [11] "Aqueous; River/Stream" "Sediment; River/Stream" ## [13] "Aqueous; Other-Surface Water" "Aqueous; River/Stream Perennial" ## [15] "Aqueous; River/Stream Intermittent" "Aqueous; River/stream Effluent-Dominated" ## [17] "Aqueous; Channelized Stream" "Aqueous; Wetland Palustrine-Shrub-Scrub"
WQP_new <- WQP_new %>% filter(MatrixName !='Soil') %>% mutate(WBT = recode(WBT, "Stream" = "River/Stream", "Stream: Ditch" = "Drain/Canal", "Stream: Canal" = "Drain/Canal", "Estuary" = "Bay/Estuary", #2019-04-02 ~ added by Robin so "Bay/Estuary" is consistent between scripts #"Other-Surface Water" = "Not Recorded", #JF decided to leave 'other - surface water' as a designation #b/c it gives some info that the WBT is not a normal surface water WBT #like the others listed (stream/river, wetland, etc.) "River/Stream Intermittent" = "River/Stream", "Channelized Stream" = "Drain/Canal", "Wetland Palustrine-Shrub-Scrub" = "Wetland", "River/Stream Perennial" = "River/Stream"), MatrixName = ifelse(Analyte_part2 == 'Bed Sediment' & MatrixName == 'Aqueous', 'Sediment', MatrixName) ) unique(paste(WQP_new$MatrixName, WQP_new$WBT, sep='; '))
## [1] "Aqueous; River/Stream" "Aqueous; Drain/Canal" ## [3] "Sediment; River/Stream" "Aqueous; Spring" ## [5] "Sediment; Bay/Estuary" "Aqueous; Bay/Estuary" ## [7] "Aqueous; Wetland" "Sediment; Spring" ## [9] "Sediment; Drain/Canal" "Aqueous; Other-Surface Water" ## [11] "Aqueous; River/stream Effluent-Dominated"
# Standardize Analyte Groups # unique(WQP_new$Analyte)
## [1] "Mercury" "Methylmercury(1+)"
unique(WQP_new$Analyte_part2)
## [1] "Dissolved" "Recoverable" "Suspended" "Bed Sediment" ## [5] "Total" NA "Total Recoverable"
unique(paste(WQP_new$Analyte, WQP_new$Analyte_part2, sep=', '))
## [1] "Mercury, Dissolved" "Mercury, Recoverable" ## [3] "Mercury, Suspended" "Mercury, Bed Sediment" ## [5] "Methylmercury(1+), Suspended" "Methylmercury(1+), Dissolved" ## [7] "Mercury, Total" "Methylmercury(1+), Total" ## [9] "Methylmercury(1+), Recoverable" "Mercury, NA" ## [11] "Mercury, Total Recoverable"
WQP_new <- WQP_new %>% mutate(Analyte = recode(Analyte, "Methylmercury(1+)" = "Methylmercury" #suspended mercury was preserved - no name change required ), #suspended mercury is all in a water matrix from surface water WBTs, with some units of ng/L and some in mg/Kg #(I guess this depends on how the concentration is calculated - either from the volume of water #or the mass of sediment that stays on the filter with it?) Analyte_part2 = recode(Analyte_part2, "Recoverable" = "Total", "Total Recoverable" = "Total", "Bed Sediment" = "Total" #Bed Sediment is the matrix and assumed to be total fraction ), Analyte_part2 = case_when(is.na(Analyte_part2) ~ "Total", #NA's only for sediment matrix and assumed to be total fraction TRUE ~ Analyte_part2) ) #Create 'Analyte' column from Analyte & Analyte_part2 columns - then delete Analyte_part2 column## WQP_new <- WQP_new %>% mutate(Analyte = paste(Analyte, Analyte_part2, sep=', ')) %>% select(-Analyte_part2) #Remove 'Analyte_part2' column unique(WQP_new$Analyte)
## [1] "Mercury, Dissolved" "Mercury, Total" "Mercury, Suspended" ## [4] "Methylmercury, Suspended" "Methylmercury, Dissolved" "Methylmercury, Total"
# Standardize ResultQualCode Groups # unique(WQP_new$ResultQualCode)
## [1] "Not Detected" NA ## [3] "Systematic Contamination" "Detected Not Quantified" ## [5] "*Non-detect" "Present Below Quantification Limit" ## [7] "Not Reported"
# Jennie determined data noted as 'Not Recorded' is not in R5 Scope and will be removed after GIS filtering - left it as is for now. WQP_new <- WQP_new %>% mutate(ResultQualCode = ifelse(is.na(StatisticalBaseCode), ResultQualCode, ifelse(is.na(ResultQualCode), StatisticalBaseCode, paste(ResultQualCode, StatisticalBaseCode, sep = ', ')) ), ResultQualCode = gsub('NA', '', ResultQualCode), # fix issues of pasting instances with NAs ResultQualCode = gsub('^(, )+|(, )+$', '', ResultQualCode), ResultQualCode = recode(ResultQualCode, ###if in the future we do an additional data run, may need to do additional recoding if there is #a result pasted above that includes results for both 'StatisticBaseCode' and 'ResultQualCode' (e.g. if ND, mean #is pasted, these individually won't be recoded because they will be seen as a string of different characters) "Not Detected" = "ND", "Detected Not Quantified" = "DNQ", "*Non-detect" = "ND", "Present Below Quantification Limit" = "DNQ", "MPN" = "E", "mean" = "AVG", .missing = "=" #replaces NA's with '=' ) ) %>% filter(ResultQualCode %are not% c('Systematic Contamination'))#Remove rows where ResultQualCode is "Systematic Contamination" because Result value is not trustworthy unique(WQP_new$ResultQualCode)
## [1] "ND" "=" "AVG" "E" "DNQ" ## [6] "Not Reported"
nrow(WQP_new)
## [1] 28136
# Format Result Column to Numeric# # Check column for text - based on text user needs to decide what to do if(any(grepl('[a-df-zA-DF-Z]',WQP_new$Result))){ old <-WQP_new$Result new <-WQP_new$Result new[grepl('[a-df-zA-DF-Z]', new)] <- NA #skip 'e' for exponential notation e.g., "8e-005" #Print what text was found and what is being done cat(paste0("'Result' column should be numeric but some cells contain ", grammaticList(setdiff(old, new)), ".\nFor these cases, ND was recorded in the 'ResultQualCode' column and NA recorded in 'Result' column.\n")) WQP_new <- WQP_new %>% mutate( ResultQualCode = case_when(Result == 'ND' ~ 'ND', TRUE ~ ResultQualCode), Result = abs(as.numeric(new)) #absolute value because some values seem to be have negative sign as typo ) } else { cat("'Result' column converted to numeric format") WQP_new$Result <- as.numeric(WQP_new$Result)}
## 'Result' column should be numeric but some cells contain ND. ## For these cases, ND was recorded in the 'ResultQualCode' column and NA recorded in 'Result' column.
# Format MDL Column to Numeric# # Check column for text - based on text user needs to decide what to do if(any(grepl('[a-df-zA-DF-Z]',WQP_new$MDL))){ old <-WQP_new$MDL new <-WQP_new$MDL new[grepl('[a-df-zA-DF-Z]', new)] <- NA #skip 'e' for exponential notation e.g., "8e-005" #Print what text was found and what is being done cat(paste0("'MDL' column should be numeric but some cells contain ", grammaticList(setdiff(old, new)), ".\nDESCRIBE WHAT WAS DONE.\n")) #Due Stuff } else { cat("'MDL' column converted to numeric format") WQP_new$MDL <- as.numeric(WQP_new$MDL)}
## 'MDL' column converted to numeric format
# RL Column created from MDL column in code ~line 346 # # Some Result values are 0. Jennie confirmed these results are most likely DNQs # Where Result = 0 & MDL not NA -> ResultQualCode='DNQ'; Result=NA WQP_new <- WQP_new %>% mutate( ResultQualCode = case_when(Result == 0 & !is.na(MDL) ~ 'DNQ', TRUE ~ ResultQualCode), Result = case_when(Result == 0 ~ NA_real_, TRUE ~ Result) ) # Check if Result, MDL, & RL Columns all equal <NA> or 0 - these rows have no useful information nrow(WQP_new) #Number rows before
## [1] 28136
#CODE BELOW REQUIRES USER TROUBLESHOOTING DEPENDING ON AVAILABLE COLUMNS AND SPREADSHEET SPECIFIC CONDITIONS# WQP_new <- WQP_new %>% #Set 0 & negative values as blank mutate(Result = ifelse(Result <= 0, NA_real_, Result), MDL = ifelse(MDL <= 0, NA_real_, MDL)) na_results <- WQP_new %>% #Record rows where Result, MDL, & RL all equal <NA> filter( is.na(Result) & is.na(MDL) ) nrow(na_results)
## [1] 1038
WQP_new <- anti_join(WQP_new, na_results, by='SourceRow') #returns rows from WQP_new not matching values in no_result nrow(WQP_new) #Number rows after
## [1] 27098
# Format Result, Unit, & MDL Columns to ng/L or mg/Kg - Only want a singe Unit column # unique(WQP_new$Unit)
## [1] NA "ug/l" "mg/kg" "ng/l" "ug/kg" "ppm" "mg/l" "ug/g"
# See if Result Units and `DetectionQuant...Code` are the same so same tranformation can be applied to Result and MDL columns identical(WQP_new$Unit, WQP_new$`DetectionQuantitationLimitMeasure/MeasureUnitCode`)
## [1] FALSE
#identical()=FALSE because when Result is blank there is no Unit entry but there is for `DetectionQuant...Code` (and vice versa). #So when no Result, use the `DetectionQuant...Code` unit if provided (and vice versa) WQP_new <- WQP_new %>% mutate( Unit = case_when(is.na(Result) ~ `DetectionQuantitationLimitMeasure/MeasureUnitCode`, TRUE ~ Unit), `DetectionQuantitationLimitMeasure/MeasureUnitCode` = case_when(is.na(`DetectionQuantitationLimitMeasure/MeasureUnitCode`) ~ Unit, TRUE ~ `DetectionQuantitationLimitMeasure/MeasureUnitCode`) ) identical(WQP_new$Unit,WQP_new$`DetectionQuantitationLimitMeasure/MeasureUnitCode`)
## [1] FALSE
#identical()=FALSE? see why... #test <- WQP_new %>% # filter(Unit != `DetectionQuantitationLimitMeasure/MeasureUnitCode`) #View(test) #identical()=FALSE because instances where Unit="ug/g", `DetectionQuant...Code`="ppm" #for this case change `DetectionQuant...Code`="ppm" to "ug/g" WQP_new <- WQP_new %>% mutate( `DetectionQuantitationLimitMeasure/MeasureUnitCode` = case_when(`DetectionQuantitationLimitMeasure/MeasureUnitCode`=='ppm' & Unit=='ug/g' ~ 'ug/g', TRUE ~ `DetectionQuantitationLimitMeasure/MeasureUnitCode`) ) identical(WQP_new$Unit,WQP_new$`DetectionQuantitationLimitMeasure/MeasureUnitCode`)
## [1] TRUE
#identical()=TRUE so now can use Unit column as basis for transforming Result and MDL values # MDL Column contains both MDL and RL values so spilt MDL column into MDL & RL Columns based on conditions using DetectionQuantitationLimitTypeName # # https://stackoverflow.com/questions/22337394/combine-mutate-with-conditional-values unique(WQP_new$DetectionQuantitationLimitTypeName)
## [1] "Historical Lower Reporting Limit" NA ## [3] "Laboratory Reporting Level" "Long Term Method Detection Level" ## [5] "Lower Reporting Limit" "Method Detection Limit (MDL)" ## [7] "Elevated Detection Limit" "Estimated Detection Level" ## [9] "Lower Quantitation Limit" "Instrument Detection Level" ## [11] "Practical Quantitation Limit"
WQP_new <- WQP_new %>% mutate( RL = case_when(grepl('Reporting', DetectionQuantitationLimitTypeName) ~ MDL), #Creates RL column & enters MDL value where DetectionQuantitationLimitTypeName='Reporting' RL = case_when(grepl('Quantitation', DetectionQuantitationLimitTypeName) ~ MDL, #Enters MDL value in RL col where DetectionQuantitationLimitTypeName='Quantitation' TRUE ~ RL), MDL = case_when(grepl('Reporting', DetectionQuantitationLimitTypeName) ~ NA_real_, #removes MDL value where DetectionQuantitationLimitTypeName='Reporting' since value is now listed in RL col TRUE ~ MDL), MDL = case_when(grepl('Quantitation', DetectionQuantitationLimitTypeName) ~ NA_real_, #removes MDL value where DetectionQuantitationLimitTypeName='Quantitation' since value is now listed in RL col TRUE ~ MDL) )%>% mutate(Unit = ifelse(StationCode == 'NARS_WQX-NOAA 1-2', 'mg/Kg', Unit), #Specific for lowland river and delta scope -may need to add MDLs for other stations if change scope MDL = ifelse(StationCode == 'NARS_WQX-NOAA 1-2', .002, MDL) ) # unique(WQP_new$Unit)
## [1] "ug/l" "mg/kg" "ng/l" "ug/kg" "ppm" "mg/l" "ug/g" "mg/Kg"
WQP_new <- WQP_new %>% standardizeUnits %>% mutate( #WQP specific Unit = paste0(Unit, #figure out how to handle blank units; is there wet/dry info for NDs? #may want to move this part to after unit classification case_when(grepl('Dry', ResultWeightBasisText, ignore.case=TRUE) ~ ' dw', grepl('Wet', ResultWeightBasisText, ignore.case=TRUE) & !grepl('Aqueous', MatrixName, ignore.case=TRUE) ~ ' ww', TRUE ~ "") ) ) unique(WQP_new$Unit)
## [1] "ng/L" "mg/Kg dw" "ng/L dw" "mg/Kg"
# Format Date and Time Column # WQP_new <- WQP_new %>% #rowise() %>% # rowise is very slow - so used sapply to make this a rowise operation mutate( #If SampleDate & CollectioTIme are not in Character format by defualt, turn it into a character class so it exports better SampleDate = ifelse(sapply(SampleDate, is.character), SampleDate, as.character(as.Date(SampleDate))), SampleTime = ifelse(sapply(SampleTime, is.character), SampleTime, format(lubridate::ymd_hms(SampleTime), "%H:%M:%S")), #COMBINE DATE AND TIME INTO SampleDateTime COLUMN SampleDateTime = ifelse(!is.na(SampleTime), paste(SampleDate, SampleTime), paste(SampleDate, '00:00:00')), #FORMAT SampleDateTime COLUMN TO DATE FORMAT SampleDateTime = lubridate::ymd_hms(SampleDateTime) ) ### REMOVE TEMPORARY COLUMNS ### WQP_new <- WQP_new %>% select(-one_of(temp_cols)) #Remove temp columns since they are no longer needed #View(WQP_new) ## SAVE FORMATTED DATA AS EXCEL FILE ## writexl::write_xlsx(WQP_new, path='Reeval_Impl_Goals_Linkage_Analysis/Data/Aqueous/WQP_aq_sed_ceden_format.xlsx') # In excel, to convert SampleDate column to Date format # 1 - Select the date column. # 2 - Go to the Data-tab and choose "Text to Columns". # 3 - On the first screen, leave radio button on "delimited" and click Next. # 4 - Unselect any delimiter boxes (everything blank) and click Next. # 5 - Under column data format choose Date, select YMD # 6 - Click Finish.
The R session information (including the OS info, R version and all packages used):
sessionInfo()
## R version 4.2.2 (2022-10-31 ucrt) ## Platform: x86_64-w64-mingw32/x64 (64-bit) ## Running under: Windows 10 x64 (build 22621) ## ## Matrix products: default ## ## locale: ## [1] LC_COLLATE=English_United States.utf8 LC_CTYPE=English_United States.utf8 ## [3] LC_MONETARY=English_United States.utf8 LC_NUMERIC=C ## [5] LC_TIME=English_United States.utf8 ## ## attached base packages: ## [1] stats graphics grDevices utils datasets methods base ## ## other attached packages: ## [1] mgcv_1.8-41 nlme_3.1-160 lubridate_1.8.0 plotly_4.10.0 ## [5] readxl_1.4.1 actuar_3.3-0 NADA_1.6-1.1 forcats_0.5.2 ## [9] stringr_1.4.1 dplyr_1.0.9 purrr_0.3.4 readr_2.1.2 ## [13] tidyr_1.2.0 tibble_3.1.8 ggplot2_3.3.6 tidyverse_1.3.2 ## [17] fitdistrplus_1.1-8 survival_3.4-0 MASS_7.3-58.1 ## ## loaded via a namespace (and not attached): ## [1] lattice_0.20-45 assertthat_0.2.1 digest_0.6.29 utf8_1.2.2 ## [5] R6_2.5.1 cellranger_1.1.0 backports_1.4.1 reprex_2.0.2 ## [9] evaluate_0.16 highr_0.9 httr_1.4.4 pillar_1.8.1 ## [13] rlang_1.0.5 lazyeval_0.2.2 googlesheets4_1.0.1 rstudioapi_0.14 ## [17] data.table_1.14.2 Matrix_1.5-1 splines_4.2.2 webshot_0.5.3 ## [21] googledrive_2.0.0 htmlwidgets_1.5.4 munsell_0.5.0 broom_1.0.1 ## [25] compiler_4.2.2 modelr_0.1.9 xfun_0.32 pkgconfig_2.0.3 ## [29] htmltools_0.5.3 tidyselect_1.1.2 viridisLite_0.4.1 fansi_1.0.3 ## [33] crayon_1.5.1 tzdb_0.3.0 dbplyr_2.2.1 withr_2.5.0 ## [37] grid_4.2.2 jsonlite_1.8.0 gtable_0.3.1 lifecycle_1.0.1 ## [41] DBI_1.1.3 magrittr_2.0.3 scales_1.2.1 writexl_1.4.0 ## [45] cli_3.3.0 stringi_1.7.8 fs_1.5.2 xml2_1.3.3 ## [49] ellipsis_0.3.2 generics_0.1.3 vctrs_0.4.1 expint_0.1-7 ## [53] tools_4.2.2 glue_1.6.2 crosstalk_1.2.0 hms_1.1.2 ## [57] yaml_2.3.5 fastmap_1.1.0 colorspace_2.0-3 gargle_1.2.0 ## [61] rvest_1.0.3 knitr_1.40 haven_2.5.1
Sys.time()
## [1] "2024-01-04 15:34:53 PST"