New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First lmer try #104
First lmer try #104
Conversation
Okay, the misordering was coming from a merge. It should be fixed now. |
ah shoot... also realized there's some code formatting that needs to happen here. I went well past the 80 character line. Will fix before we merge. Trying to work on the var-covar part now. |
I'm done for the day but just wanted to share this quickly (haven't pushed any of this yet). m5 <- lmer(math ~ wave * sid_frl + cohort + district_prop_frl + (wave|sid) + (wave + cohort + wave:sid_frl|district), d) Overly complicated model that doesn't fit, but, with my local version anyway, you can now do this! equatiomatic:::create_vcov_structure_merMod(model) %>%
cat("$$", ., "$$") Which renders as The actual LaTeX for this is kind of crazy. It ends up looking like this.
But it all builds automatically! Still a fair amount to do, including how to work in group-level predictors (they all go to top level at this point) and building in things like align environments. I'd also like to add the "for SID j in 1,...,J" part for each level. But this is promising! |
zomg this is incredible! |
Wooohooo!!!! This is all working now. There's still a fair amount of things I'd like to implement but we're basically there for these basic models! Last thing that needs to be changed before we merge, though, is the codebase needs to be cleaned up. This is really unorganized right now. I'll work on that later today, and then we can merge it in if it all looks good to you? library(equatiomatic)
library(lme4)
#> Loading required package: Matrix
library(tidyverse)
data("benchmarks", package = "esvis")
d <- benchmarks %>%
add_count(sid) %>%
filter(n == 3) %>%
mutate(wave = case_when(season == "Fall" ~ 0,
season == "Winter" ~ 1,
TRUE ~ 2))
set.seed(123)
d$district <- rep(sample(1:9), length.out = nrow(d))
d <- d %>%
count(district, frl) %>%
pivot_wider(names_from = frl, values_from = n) %>%
mutate(district_prop_frl = FRL / (FRL + `Non-FRL`)) %>%
select(district, district_prop_frl) %>%
right_join(d) %>%
rename(sid_frl = frl)
#> Joining, by = "district"
m0 <- lmer(math ~ 1 + (1|sid), d)
extract_eq(m0)
#> Registered S3 method overwritten by 'broom.mixed':
#> method from
#> tidy.gamlss broom m1 <- lmer(math ~ 1 + wave + (1|sid), d)
extract_eq(m1) m2 <- lmer(math ~ 1 + wave + (wave|sid), d)
extract_eq(m2) m3 <- lmer(math ~ 1 + wave + (wave|sid) + (1|district), d)
#> boundary (singular) fit: see ?isSingular
extract_eq(m3) m4 <- lmer(math ~ 1 + wave*cohort + (wave|sid) + (wave*cohort|district), d)
#> boundary (singular) fit: see ?isSingular
extract_eq(m4) |
Magical. Kicking the tires, on this branch:
After building the package, I got what is probably a super easy to fix namespace error for library(lme4)
#> Loading required package: Matrix
library(equatiomatic)
fm1 <- lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
extract_eq(fm1)
#> Registered S3 method overwritten by 'broom.mixed':
#> method from
#> tidy.gamlss broom
#> Error in str_split(text, " "): could not find function "str_split" Created on 2020-09-02 by the reprex package (v0.3.0) |
Ah shoot! I meant to use |
library(lme4)
#> Loading required package: Matrix
library(equatiomatic)
fm1 <- lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
extract_eq(fm1)
#> Registered S3 method overwritten by 'broom.mixed':
#> method from
#> tidy.gamlss broom Seriously magical. I will try a few more examples. My challenge now is not fully understanding the Gelman and Hill notation... wondering if some kind of documentation around how to "translate" between the Raudenbush & Bryk-esque notation and it might help others like me. On that note, perhaps as a newcomer to this notation I can find the section of Data Analysis Using Regression and Multilevel/Hierarchical Models where they show five (or six?) ways to write the same model... |
Thanks, that would be super helpful. Also - I realize the tests are failing. I'll fix that later tonight too when I organize the codebase a bit better. |
This is absolutely amazing. |
Okay, I just documented all the functions and cleaned up the codebase some (gave better names to a few functions, etc.). The next thing I really want to implement is being able to define group-level coefficients. I have a few ideas on that, but I think this probably ready to merge in? |
Okay, I refactored the code and fixed a couple small bugs. I also added wrapping and the ability to have the mean structure inside or outside of the normal distribution part. I called that argument I will wait until this evening but I do believe this is officially ready to merge, and then we can submit new PRs for further development (e.g. #105). @bbolker would you possibly have time to glance at the below and let me know if anything looks incorrect? Also, I'm currently using library(equatiomatic)
library(lme4)
library(tidyverse)
data("benchmarks", package = "esvis")
d <- benchmarks %>%
add_count(sid) %>%
filter(n == 3) %>%
mutate(wave = case_when(season == "Fall" ~ 0,
season == "Winter" ~ 1,
TRUE ~ 2))
set.seed(123)
d$district <- rep(sample(1:9), length.out = nrow(d))
d <- d %>%
count(district, frl) %>%
pivot_wider(names_from = frl, values_from = n) %>%
mutate(district_prop_frl = FRL / (FRL + `Non-FRL`)) %>%
select(district, district_prop_frl) %>%
right_join(d) %>%
rename(sid_frl = frl)
m0 <- lmer(math ~ 1 + (1|sid), d)
extract_eq(m0) m1 <- lmer(math ~ 1 + wave + (1|sid), d)
extract_eq(m1) m2 <- lmer(math ~ 1 + wave + (wave|sid), d)
extract_eq(m2) m3 <- lmer(math ~ 1 + wave + (wave|sid) + (1|district), d)
extract_eq(m3) m4 <- lmer(math ~ 1 + wave*cohort + (wave|sid) + (wave*cohort|district), d)
extract_eq(m4) Show wrappingm5 <- lmer(math ~ wave*cohort + district_prop_frl +
(wave|sid) + (wave*cohort|district),
data = d)
extract_eq(m5, wrap = TRUE, terms_per_line = 2) Show wrapping inside normal distributionextract_eq(m5, wrap = TRUE, terms_per_line = 2, mean_separate = FALSE) |
Wow! I'll take a look. If you need to access |
It's not a huge deal, but because already use
|
The correct way to get around this would be to have the PS it's rather confusing but this suggests that the |
Went ahead and merged this in. I have a nearly working branch on my local to incorporate group-level predictors. Will have a PR for that soon. |
This is not complete, but if you look at may last comment from #22 you'll see that all equations basically have a "distributed as" part and a variance/covariance part. This PR is the first try at getting the "distributed as" part. Only part way there, but I think it's a pretty good step. Examples below. I put all of this in a new R file for now.
For some reason the variable ordering is not holding. I'll look into that and get that fixed before we merge.