I am trying to see if some anthropic variables (e.g., PopdensityAvg
) explain animals' distribution. My dependent variable is the area occupied (non_null_cells
) over the total area of interest (PAR
), which can be expressed both as a percentage (range_perc
, continuous variable, range: 0-100; e.g., 87.9) and as a proportion (range_prop
, ranging 0-1, e.g. 0.87).
Each species has also a status (Establishment
, discrete variable; i.e., 0/1), and I expect to have different influences of each independent variable, based on species' status. For instance, for a species with status 0, I expect no influence of Roads, while for a species with status 1, I expect an influence of Roads.
The values of the independent variables are averaged and measured throughout the species distribution range. Some of these independent variables can have a negative value (e.g., PopgrowthAvg
). The data looks like this:
Binomial Establishment PAR non_null_cells range_prop range_perc PopdensityAvg PopgrowthAvg Railways Roads
1 Ammotragus_lervia 1 10840225 10762611 0.9928402 99.28402 68.68320 1.8325691 0.5568174 2.265508
2 Ammotragus_lervia_NE 0 10699087 10621473 0.9927457 99.27457 69.58296 1.8520451 0.5631284 2.288850
3 Apodemus_sylvaticus 1 2334776 2158612 0.9245478 92.45478 139.97713 2.6652732 0.9798067 2.927115
4 Atelerix_algirus 1 438917 383734 0.8742746 87.42746 76.02714 2.4077785 0.6011552 2.380663
5 Axis_axis 1 2072 1970 0.9507722 95.07722 19.40114 0.1917508 0.0000000 2.354487
6 Axis_axis_NE 0 18804 18804 1.0000000 100.00000 97.61798 2.7962866 0.3156403 2.715702
I got the recommendation of beta regression (from betareg
package in R), but I have many 0's and 1's in range_prop
. If I perform the suggested transformation (from an answer here Dealing with 0,1 values in a beta regression , "if y also assumes the extremes 0 and 1, a useful transformation in practice is (y * (n−1) + 0.5) / n where n is the sample size", it transforms my 1's in 0.95, and I don't know how good is that for my model, as I am very interested in outputs from observations with a range_prop
value of 1).
I switched to GLM
(package stats
, I don't know if there are better options) thinking it would be better. I think I should use a Gamma distribution, based on the response variable (that is > 0 and is continuous). I understand that as my response variable's upper limit is 1 (or 100, if we consider range_perc
), a beta regression would likely perform better compared to a Gamma distribution (that, if I am correct, assumes just values > 0, without an upper limit), but I don't know how to deal with so many 0's and 1's, and I do not understand if I should transform my data to comply with a particular modelling algorithm or if I can safely switch to more generalized techniques (such as GLMs
).
I am wondering if my reasonings are correct, and also how to deal with negative values in the independent variables (such as the ones in PopgrowthAvg
, not present in the sample data I show here).
Edit:
In my data, I also have the total area of interest, from which I extracted range_perc
and range_prop
for each species in Binomial
. I added it to the sample data.
I am using R 4.0.3
Edit n.2: After the useful answers, I tried a GLM with binomial distribution. As in Dunn & Smyth book on GLMs,
Binomial responses may be specified in the glm() formula in one of three ways:
- The response can be supplied as the observed proportions yi, when the sample sizes mi are supplied as the weights in the call to glm().
- The response can be given as a two-column array, the columns giving the numbers of successes and failures respectively in each group of size mi. The prior weights weights do not need to be supplied (r computes the weights m as the sum of the number of successes and failures for each row).
I tried both:
- First approach
col_glm <- cbind(myData$non_null_cells, ((myData$PAR)-(myData$non_null_cells)))
#use a 2 column matrix as the response variable with the first column being the counts of 'successes' and the second column being the counts of 'failures'
#in this case, successes are the cells occupied by the species range (non_null_cells) and failures is the total area (PAR - non_null_cells)
glm2.2 <- glm(col_glm ~ PopdensityAvg + PopgrowthAvg + Railways + Roads,
family = binomial,
data = myData)
summary(glm2.2)
Call:
glm(formula = col_glm ~ PopdensityAvg + PopgrowthAvg + Railways +
Roads, family = binomial, data = myData)
Deviance Residuals:
Min 1Q Median 3Q Max
-2612.51 2.49 129.26 610.45 1722.15
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.05252214 0.00230722 -456.2 <0.0000000000000002 ***
PopdensityAvg -0.05356983 0.00002347 -2282.4 <0.0000000000000002 ***
PopgrowthAvg 0.31591664 0.00027212 1160.9 <0.0000000000000002 ***
Railways 7.23302791 0.00304914 2372.2 <0.0000000000000002 ***
Roads 0.80775145 0.00109461 737.9 <0.0000000000000002 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 60080855 on 94 degrees of freedom
Residual deviance: 52299051 on 90 degrees of freedom
AIC: 52299902
Number of Fisher Scoring iterations: 6
- Second approach
glm2.3 <- glm(range_prop ~ PopdensityAvg + PopgrowthAvg + Railways + Roads,
weights = myData$PAR,
family = binomial,
data = myData)
#specify the response as a proportion between 0 and 1, then specify another column as the 'weight' that gives the total number that the proportion is from
summary(glm2.3)
Call:
glm(formula = range_prop ~ PopdensityAvg + PopgrowthAvg + Railways +
Roads, family = binomial, data = myData, weights = myData$PAR)
Deviance Residuals:
Min 1Q Median 3Q Max
-2612.51 2.49 129.26 610.45 1722.15
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.05252214 0.00230722 -456.2 <0.0000000000000002 ***
PopdensityAvg -0.05356983 0.00002347 -2282.4 <0.0000000000000002 ***
PopgrowthAvg 0.31591664 0.00027212 1160.9 <0.0000000000000002 ***
Railways 7.23302791 0.00304914 2372.2 <0.0000000000000002 ***
Roads 0.80775145 0.00109461 737.9 <0.0000000000000002 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 60080855 on 94 degrees of freedom
Residual deviance: 52299051 on 90 degrees of freedom
AIC: 52299902
Number of Fisher Scoring iterations: 6
The outputs are the same. I tried, with my naive knowledge, to interpret the results.
The Deviance Residuals
seem to have a high median value and 1Q and 3Q to be substantially apart, which I guess is not good.
Null deviance
and Residual deviance
are very high as well. Again: I guess it's not good.
Warning message: glm.fit: fitted probabilities numerically 0 or 1 occurred
. I have some extreme values (both in my dependent variablerange_perc
and in my predictors, e.g.,PopdensityAvg
), skewing the data, as you can see:> summary(myData$PopdensityAvg) Min. 1st Qu. Median Mean 3rd Qu. Max. 0.00 63.58 91.81 158.01 147.21 2447.92 > summary(myData$range_perc) Min. 1st Qu. Median Mean 3rd Qu. Max. 0.00922 58.32962 96.58130 79.00526 99.76029 100.00000
. Maybe I shall try again, removing them. $\endgroup$