Closed paulofelipe closed 6 months ago
Hi @paulofelipe, sorry this completely slipped through the cracks. I only saw it again now after responding to another issue. There's a lot going on in the above code. Can you simplify it and just highlight the key discrepancy that you're wondering about? That will make it easier for me to help you.
Hi, @grantmcdermott. I apologize for not being concise in my initial question. My doubt pertains to the value obtained for the Simple ATT using the following code:
library(did)
library(etwfe)
library(broom)
library(stringr)
library(marginaleffects)
library(fixest)
library(dplyr)
mpdta <- did::mpdta %>%
mutate(
.Dtreat = treat * (year >= first.treat),
time_to_event = ifelse(first.treat != 0, year - first.treat, -1000)
)
etwfe_never <- etwfe(
fml = lemp ~ 1,
tvar = year,
gvar = first.treat,
data = mpdta,
ivar = countyreal,
cgroup = "never"
)
emfx(etwfe_never, "simple") %>%
tidy() %>%
print()
#> # A tibble: 1 × 13
#> term contrast .Dtreat estimate std.error statistic p.value s.value conf.low
#> <chr> <chr> <lgl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 .Dtreat mean(TR… TRUE -0.00166 0.00489 -0.339 0.735 0.445 -0.0112
#> # ℹ 4 more variables: conf.high <dbl>, predicted <dbl>, predicted_hi <dbl>,
#> # predicted_lo <dbl>
slopes(
model = etwfe_never,
newdata = mpdta %>% filter(.Dtreat == 1),
variable = ".Dtreat",
by = ".Dtreat"
) %>%
print()
#>
#> Term Contrast .Dtreat Estimate Std. Error z Pr(>|z|)
#> .Dtreat mean(TRUE) - mean(FALSE) 1 -0.0404 0.0196 -2.06 0.0396
#> S 2.5 % 97.5 %
#> 4.7 -0.0789 -0.00193
#>
#> Columns: term, contrast, .Dtreat, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high, predicted, predicted_hi, predicted_lo
The obtained result (-0.00166) using the “never treated” group as the control diverges significantly from that obtained using the “not yet treated” control group (-0.0477) and from the manually calculated simple ATT values (-0.0404) using the marginaleffects package. Perhaps the code I used with the slopes() function is incorrect, but I can replicate the results (using emfx and slopes) when I change to cgroup = "notyet" in the etwfe() function.
Thanks in advance.
Ah, I see. Thanks @paulofelipe. I think this might be a subsetting bug for the never-treated case. Let me dig a little deeper and confirm.
Hi again @paulofelipe. Thanks again for reporting this and bearing with my tawdry response. It was indeed a bug, so I'm very grateful that you brought it to my attention. It should be fixed now if you grab the latest development version.
Quick MWE based off of your example.
library(etwfe)
data("mpdta", package = "did")
etwfe_never = etwfe(
fml = lemp ~ 1,
tvar = year,
gvar = first.treat,
data = mpdta,
ivar = countyreal,
cgroup = "never"
)
emfx(etwfe_never, "simple")
#>
#> Term Contrast .Dtreat Estimate Std. Error z Pr(>|z|)
#> .Dtreat mean(TRUE) - mean(FALSE) TRUE -0.04 0.0118 -3.39 <0.001
#> S 2.5 % 97.5 %
#> 10.5 -0.0631 -0.0168
#>
#> Columns: term, contrast, .Dtreat, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high, predicted_lo, predicted_hi, predicted
#> Type: response
emfx(etwfe_never, "event")
#>
#> Term Contrast event Estimate Std. Error z Pr(>|z|)
#> .Dtreat mean(TRUE) - mean(FALSE) -4 0.00331 0.0246 0.135 0.89289
#> .Dtreat mean(TRUE) - mean(FALSE) -3 0.02502 0.0182 1.378 0.16812
#> .Dtreat mean(TRUE) - mean(FALSE) -2 0.02446 0.0143 1.714 0.08646
#> .Dtreat mean(TRUE) - mean(FALSE) -1 0.00000 NA NA NA
#> .Dtreat mean(TRUE) - mean(FALSE) 0 -0.01993 0.0119 -1.681 0.09277
#> .Dtreat mean(TRUE) - mean(FALSE) 1 -0.05096 0.0169 -3.020 0.00252
#> .Dtreat mean(TRUE) - mean(FALSE) 2 -0.13726 0.0366 -3.751 < 0.001
#> .Dtreat mean(TRUE) - mean(FALSE) 3 -0.10081 0.0345 -2.922 0.00348
#> S 2.5 % 97.5 %
#> 0.2 -0.0448 0.05143
#> 2.6 -0.0106 0.06060
#> 3.5 -0.0035 0.05242
#> NA NA NA
#> 3.4 -0.0432 0.00331
#> 8.6 -0.0840 -0.01789
#> 12.5 -0.2090 -0.06554
#> 8.2 -0.1684 -0.03318
#>
#> Columns: term, contrast, event, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high, predicted_lo, predicted_hi, predicted
#> Type: response
Created on 2024-02-25 with reprex v2.1.0
Hi, @grantmcdermott
Nice! Thank you for providing the new version!
Fixed version (v0.4.0) is up on CRAN now too.
Hi @grantmcdermott ,
First of all, thank you for providing this valuable package. It has been instrumental in helping me understand the implementation details of the Extended Two-Way Fixed Effects method developed by Wooldridge.
I do, however, have a question regarding the computation of the simple ATT using a never treated control group. In my experiments, I have noticed significant differences between the results obtained from the etwfe function and those obtained from the Callaway-Sanntanna estimator, as well as when I manually run the etwfe procedure.
After executing the etwfe function, I computed the simple ATT using the marginaleffects::slopes() function and obtained an estimate of -0.0404, whereas the estimate I obtained using emfx() was -0.00166.
I must be overlooking some important detail. To provide further context, I have attached the details of my experiments below.
Thank you in advance!
Created on 2023-06-21 with reprex v2.0.2