11"""
2- AbstractDiffinDiffs
2+ DiffinDiffsEstimator <: AbstractStatsProcedure
33
44Supertype for all types specifying the estimation procedure for difference-in-differences.
55"""
6- abstract type AbstractDiffinDiffs end
6+ abstract type DiffinDiffsEstimator <: AbstractStatsProcedure end
77
88"""
9- DefaultDID <: AbstractDiffinDiffs
9+ DefaultDID <: DiffinDiffsEstimator
1010
11- Try to use a default procedure based on other information .
11+ Default difference-in-differences estimator selected based on the context .
1212"""
13- struct DefaultDID <: AbstractDiffinDiffs end
13+ struct DefaultDID <: DiffinDiffsEstimator end
1414
1515did (tr:: AbstractTreatment , pr:: AbstractParallel ; kwargs... ) =
1616 did (DefaultDID, tr, pr; kwargs... )
1717
1818# The only case in which a message replaces MethodError
19- did (d:: Type{<:AbstractDiffinDiffs } , tr:: AbstractTreatment , pr:: AbstractParallel ; kwargs... ) =
19+ did (d:: Type{<:DiffinDiffsEstimator } , tr:: AbstractTreatment , pr:: AbstractParallel ; kwargs... ) =
2020 error (" $(typeof (d)) is not implemented for $(typeof (tr)) and $(typeof (pr)) " )
2121
2222"""
23- did(d::Type{<:AbstractDiffinDiffs }, t::TreatmentTerm, args...; kwargs...)
23+ did(d::Type{<:DiffinDiffsEstimator }, t::TreatmentTerm, args...; kwargs...)
2424
2525A wrapper method that accepts a [`TreatmentTerm`](@ref).
2626"""
27- did (d:: Type{<:AbstractDiffinDiffs } , @nospecialize (t:: TreatmentTerm ), args... ; kwargs... ) =
27+ did (d:: Type{<:DiffinDiffsEstimator } , @nospecialize (t:: TreatmentTerm ), args... ; kwargs... ) =
2828 did (d, t. tr, t. pr, args... ; treatname= t. sym, kwargs... )
2929
3030"""
31- did(d::Type{<:AbstractDiffinDiffs }, formula::FormulaTerm, args...; kwargs...)
31+ did(d::Type{<:DiffinDiffsEstimator }, formula::FormulaTerm, args...; kwargs...)
3232
3333A wrapper method that accepts a formula.
3434"""
35- function did (d:: Type{<:AbstractDiffinDiffs } , @nospecialize (formula:: FormulaTerm ),
35+ function did (d:: Type{<:DiffinDiffsEstimator } , @nospecialize (formula:: FormulaTerm ),
3636 args... ; kwargs... )
3737 treat, intacts, xs = parse_treat (formula)
3838 ints = intacts== () ? NamedTuple () : (treatintterms= intacts,)
@@ -41,25 +41,8 @@ function did(d::Type{<:AbstractDiffinDiffs}, @nospecialize(formula::FormulaTerm)
4141 yterm= formula. lhs, treatname= treat. sym, ints... , xterms... , kwargs... )
4242end
4343
44- """
45- args_kwargs(exprs)
46-
47- Partition a collection of expressions into two arrays
48- such that all expressions in the second array has `head` being `:(=)`.
49- This function is useful for separating out expressions
50- for positional arguments and those for keyword arguments.
51- """
52- function args_kwargs (exprs)
53- args = []
54- kwargs = []
55- for expr in exprs
56- (expr isa Expr && expr. head== :(= )) ? push! (kwargs, expr) : push! (args, expr)
57- end
58- return args, kwargs
59- end
60-
44+ argpair (arg:: Type{<:DiffinDiffsEstimator} ) = :d => arg
6145argpair (arg:: AbstractString ) = :name => String (arg)
62- argpair (arg:: Type{<:AbstractDiffinDiffs} ) = :d => arg
6346argpair (arg:: AbstractTreatment ) = :tr => arg
6447argpair (arg:: AbstractParallel ) = :pr => arg
6548argpair (:: Any ) = throw (ArgumentError (" unacceptable positional arguments" ))
@@ -68,24 +51,16 @@ argpair(::Any) = throw(ArgumentError("unacceptable positional arguments"))
6851 parse_didargs(args...; kwargs...)
6952
7053Classify positional arguments for [`did`](@ref) by type
71- and parse any [`TreatmentTerm`](@ref) or [`FormulaTerm`](@ref) in `args`.
72- The order of positional arguments in `args` does not make a difference.
54+ and parse any [`TreatmentTerm`](@ref) or [`FormulaTerm`](@ref).
55+ The order of positional arguments is irrelevant.
56+ This function helps constructing a [`StatsSpec`](@ref)
57+ that can be accepted by [`did`](@ref).
7358
7459# Returns
75- - `String`: optional name for [`DIDSpec`](@ref) (return `""` if no instance of a subtype of `AbstractString` is found).
76- - `Dict`: up to three key-value pairs for processed positional arguments.
77- - `Dict`: keyword arguments with possibly additional pairs after parsing `args`.
78-
79- # Notes
80- The possible keys for the first `Dict` are `:d`, `:tr` and `:pr`.
81- They are used to index a subtype of [`AbstractDiffinDiffs`](@ref),
82- instances of [`AbstractTreatment`](@ref) and [`AbstractParallel`](@ref) respectively.
83-
84- If `args` contains any [`TreatmentTerm`](@ref) or [`FormulaTerm`](@ref),
85- they are decomposed with additional key-value pairs
86- joining the other keyword arguments in the second `Dict`.
87-
88- This function is useful for constructing [`DIDSpec`](@ref).
60+ - `Type{<:DiffinDiffsEstimator}`: either the type found in positional arguments or `DefaultDID`.
61+ - `String`: either a string found in positional arguments or `""` if no instance of any subtype of `AbstractString` is found.
62+ - `Dict`: up to two key-value pairs for instances of [`AbstractTreatment`](@ref) and [`AbstractParallel`](@ref) with keys being `:tr` and `:pr`.
63+ - `Dict`: keyword arguments with possibly additional pairs after parsing positional arguments.
8964"""
9065function parse_didargs (args... ; kwargs... )
9166 pargs = Pair{Symbol,Any}[]
@@ -108,36 +83,40 @@ function parse_didargs(args...; kwargs...)
10883 kwargs = Dict {Symbol,Any} (pkwargs... )
10984 length (args) == length (pargs) && length (kwargs) == length (pkwargs) ||
11085 throw (ArgumentError (" redundant arguments encountered" ))
86+ sptype = pop! (args, :d , DefaultDID)
11187 name = pop! (args, :name , " " )
112- return name, args, kwargs
88+ return sptype, name, args, kwargs
11389end
11490
11591"""
116- DIDSpec{T<:AbstractDiffinDiffs}
92+ didspec(args...; kwargs...)
11793
118- Record the positional arguments and keyword arguments for [`did`](@ref)
119- and optionally a name for the specification.
94+ Construct a [`StatsSpec`](@ref) with fields set by processed arguments.
95+ An optional `name` for [`StatsSpec`](@ref) can be included in `args` as a string.
96+ The order of positional arguments is irrelevant.
12097
121- # Fields
122- - `name::String`: name for the specification.
123- - `args::Dict{Symbol}`: positional arguments indexed based on their types.
124- - `kwargs::Dict{Symbol}`: keyword arguments.
98+ This method simply passes objects returned by [`parse_didargs`](@ref)
99+ to the constructor of [`StatsSpec`](@ref).
125100"""
126- struct DIDSpec{T<: AbstractDiffinDiffs }
127- name:: String
128- args:: Dict{Symbol}
129- kwargs:: Dict{Symbol}
130- DIDSpec (name:: String , args:: Dict{Symbol} , kwargs:: Dict{Symbol} ) =
131- new {pop!(args, :d, DefaultDID)} (name, args, kwargs)
132- end
101+ didspec (args... ; kwargs... ) = StatsSpec (parse_didargs (args... ; kwargs... )... )
102+
103+ """
104+ @didspec ["name" args... kwargs...]
133105
134- == (a :: DIDSpec{T} , b :: DIDSpec{T} ) where {T <: AbstractDiffinDiffs } =
135- a . args == b . args && a . kwargs == b . kwargs
106+ Call [`didspec`](@ref) for constructing a [`StatsSpec`](@ref).
107+ The order of arguments is irrelevant.
136108
137- isnamed (sp:: DIDSpec ) = sp. name != " "
109+ # Arguments
110+ - `name::AbstractString`: an optional name for the [`StatsSpec`](@ref).
111+ - `args... kwargs...`: a list of arguments accepted by [`did`](@ref).
112+ """
113+ macro didspec (exprs... )
114+ args, kwargs = args_kwargs (exprs)
115+ return esc (:(didspec ($ (args... ); $ (kwargs... ))))
116+ end
138117
139- function show (io:: IO , sp:: DIDSpec {T} ) where {T}
140- print (io, " DIDSpec {" , sprintcompact (T), " }" )
118+ function show (io:: IO , sp:: StatsSpec {T} ) where {T<: DiffinDiffsEstimator }
119+ print (io, " StatsSpec {" , sprintcompact (T), " }" )
141120 isnamed (sp) && print (io, " : " , sp. name)
142121 if get (io, :compact , false ) || ! haskey (sp. args, :tr ) && ! haskey (sp. args, :pr )
143122 return
@@ -149,38 +128,11 @@ function show(io::IO, sp::DIDSpec{T}) where {T}
149128end
150129
151130"""
152- spec(args...; kwargs... )
131+ did(sp::StatsSpec )
153132
154- Construct a [`DIDSpec`](@ref) with `args` and `kwargs`
155- processed by [`parse_didargs`](@ref).
156- An optional `name` for [`DIDSpec`](@ref) can be included in `args` as a string.
157-
158- This method simply passes objects returned by [`parse_didargs`](@ref)
159- to the constructor of [`DIDSpec`](@ref).
160- """
161- spec (args... ; kwargs... ) = DIDSpec (parse_didargs (args... ; kwargs... )... )
162-
163- """
164- @spec ["name" args... kwargs...]
165-
166- Return a [`DIDSpec`](@ref) with fields set by the arguments.
167- The order of the arguments does not make a difference.
168-
169- # Arguments
170- - `name::AbstractString`: an optional name for the specification.
171- - `args... kwargs...`: a list of arguments for [`did`](@ref).
133+ A wrapper method that accepts a [`StatsSpec`](@ref).
172134"""
173- macro spec (exprs... )
174- args, kwargs = args_kwargs (exprs)
175- return esc (:(spec ($ (args... ); $ (kwargs... ))))
176- end
177-
178- """
179- did(sp::DIDSpec)
180-
181- A wrapper method that accepts a [`DIDSpec`](@ref).
182- """
183- function did (sp:: DIDSpec{T} ) where {T}
135+ function did (sp:: StatsSpec{T} ) where {T<: DiffinDiffsEstimator }
184136 if haskey (sp. args, :tr ) && haskey (sp. args, :pr )
185137 did (T, sp. args[:tr ], sp. args[:pr ]; sp. kwargs... )
186138 else
@@ -192,16 +144,11 @@ end
192144 @did args... [kwargs...]
193145
194146Call [`did`](@ref) with the specified arguments.
195- The order of the arguments does not make a difference .
147+ The order of the arguments is irrelevant .
196148"""
197149macro did (exprs... )
198150 args, kwargs = args_kwargs (exprs)
199- return esc (:(did (spec ($ (args... ); $ (kwargs... )))))
200- end
201-
202- struct DIDSpecSet
203- default:: DIDSpec
204- specs:: DIDSpec
151+ return esc (:(did (didspec ($ (args... ); $ (kwargs... )))))
205152end
206153
207154
0 commit comments