I want to iterate a chunk of code across columns in a dataframe, to create a results matrix. I am getting stuck with how to iteratively create new objects and matrices using/named after values in a certain column (Site) in my dataframe, to then pass through to the following lines of code.
The code I am wanting to iterate is:
SiteI1_data = data %>% subset(Site == I1) %>%select(x_coord, y_cood)
SiteI1_dists <- as.matrix(dist(SiteI1_data))
SiteI1_dists.inv <- 1/SiteI1_dists
diag(SiteI1_dists.inv) <- 0
Resid_taxa1_siteI1 <- as.vector( Resid_data %>% subset(Site == I1) %>% select(Abundance_Taxa1) )
Moran.I(Resid_taxa1_siteI1, SiteI1_dists.inv)
The "Site" names and coordinates for the first chunk of code are in the following dataframe (data):
| Sample | Site | Treatment | x_coord | y_coord | Abundance_Taxa_1 | ... | Abundance_Taxa_n |
|---|---|---|---|---|---|---|---|
| I1S1 | I1 | Inside | 140.00 | -29.00 | 56 | ... | 0 |
| O2S1 | O2 | Outside | 141.00 | -28.00 | 3 | ... | 100 |
| O2S2 | O2 | Outside | 141.10 | -28.10 | 5 | ... | 4 |
The "Abundance_Taxa_" values are stored with the associated "Site" names in a separate dataframe (Resid_data):
| Site | Abundance_Taxa_1 | ... | Abundance_Taxa_n |
|---|---|---|---|
| O1 | -0.5673 | --- | 1.1579 |
| I1 | -0.6666 | --- | 1.2111 |
There are multiple "Samples" for each "Site". The first four lines of code aim to use the x and y coordinates to create an inverse distance weights matrix for each site.
The fifth line aims to create a vector of the values in Resid_data for each site and taxa.
The final line of code uses the taxa/site vector and the previously created distance matrix to calculate Moran's I for each site and taxa. My desired outcome is to produce the following matrix:
| Site | Treatment | MoranI_Taxa_1 | ... | MoranI_Taxa_n |
|---|---|---|---|---|
| I1 | Inside | 0.1 | ... | 0.2 |
| O2 | Outside | 0.5 | ... | 0.01 |
I am not sure how to write this to
- iteratively create a distance matrix for each site, named after that site, to later pass through to the final line
- iterate the 5th line of code for each site and taxa in Resid_data (i.e., all columns beginning with "Abundance_Taxa_"), and create a vector for each
- iterate the final line for each site (e.g., for site I1, it would repeat as:
Moran.I(Resid_taxa1_siteI1, SiteI1_dists.inv)
Moran.I(Resid_taxa2_siteI1, SiteI1_dists.inv)
until it has completed for all vectors of residual values for that site).
The number of Site values is relatively small (12), but the number of "Abundance_Taxa" columns that I need to iterate through is large (~2400). Most of what I have found online has been writing very simple 'for' loops. As such, I don't even really know where to start with this.
We first define two helper functions:
calculateWeightscorresponds to your first four lines of provided code andgetResidualDatareflects the fifth line.Then your desired result can be calculated like this:
This would for example look like
using the sample data