Reputation: 1325
I have a data frame of species with different abundances and I want to see if their abundances are related to some parameter.
I think I ought to be able to do something like
# Load in the dune data set and tidyverse
library(vegan)
data(dune)
data(dune.env)
library(tidyverse)
# Reshape the species matrix into long form data
duneM <- dune %>% rownames_to_column('Site') %>% gather(Species, Count, -Site)
# Join the species and environmental data
duneE <- dune.env %>% rownames_to_column('Site')
duneJ <- left_join(duneM, duneE, by = 'Site')
# Basic linear model, that compares species counts to moisture data
my_lm <- function(df){
lm(Count ~ Moisture, data = df)
}
# Group the data by species and apply the function to each one
duneJ %>% group_by('Species') %>% map(my_lm)
To my surprise, I am getting the following error message.
Error in eval(predvars, data, env): invalid 'envir' argument of type 'character' Traceback:
- duneJ %>% group_by("Species") %>% map(my_lm)
- withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
- eval(quote(`_fseq`(`_lhs`)), env, env)
- eval(quote(`_fseq`(`_lhs`)), env, env)
- `_fseq`(`_lhs`)
- freduce(value, `_function_list`)
- withVisible(function_list[k])
- function_list[k]
- map(., my_lm)
- .f(.x[[i]], ...)
- lm(Count ~ Moisture, data = df) # at line 2 of file
- eval(mf, parent.frame())
- eval(mf, parent.frame())
- stats::model.frame(formula = Count ~ Moisture, data = df, drop.unused.levels = TRUE)
- model.frame.default(formula = Count ~ Moisture, data = df, drop.unused.levels = TRUE)
- eval(predvars, data, env)
Clearly, I am missing something here. Could somebody please clarify? Thanks.
Upvotes: 0
Views: 3925
Reputation: 1325
It helped me to look at this post http://omaymas.github.io/Climate_Change_ExpAnalysis/, and this video https://www.youtube.com/watch?v=rz3_FDVt9eg to understand how to best use purrr and broom together. As G. Grothendeik points out, I can add a column with models to a data frame (where each cell is a full model). The way to do this with the map function is
duneJ %>% group_by(Species) %>% nest %>% mutate(Mod = map(data, my_lm0)) -> test
Here, nest
is a key function that makes a column that is a list of data frames, each of which contain the data about each species and saves it to a default column named "data". I run map
inside of the mutate funciton to save the models to yet another column, where each cell is a new model.
If I want to look at model results, I can combine them into a list of data frames with map and broom, select the relevant data, and then unnest
them, like so:
test %>% mutate(Glance = map(Mod, glance)) %>% select(Species, Glance) %>% unnest
This gets me a new data frame that has model results for each species, which was what I was ultimately aiming for, even if I didn't fully explain that in the question.
Upvotes: 0