Here is one method.
DF <- data.frame(Site = c("Site1", "Site2", "Site3", "site4"),
var1 = c(1,2,0,4), var2 = c(3,6,4,0),
var3 = c(0,6,3,2))
DF
#> Site var1 var2 var3
#> 1 Site1 1 3 0
#> 2 Site2 2 6 6
#> 3 Site3 0 4 3
#> 4 site4 4 0 2
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
DF <- DF |> mutate(across(.cols = var1:var3,
.fns = ~ifelse(.x == 0, mean(.x), .x)))
DF
#> Site var1 var2 var3
#> 1 Site1 1.00 3.00 2.75
#> 2 Site2 2.00 6.00 6.00
#> 3 Site3 1.75 4.00 3.00
#> 4 site4 4.00 3.25 2.00
Created on 2022-02-02 by the reprex package (v2.0.1)
Note that using this "mean" value might give strange results if many of the values in a column have been replaced with zero.