【问题标题】:R: how to call feols regression within a functionR:如何在函数中调用 feols 回归
【发布时间】:2021-12-05 04:42:40
【问题描述】:

我正在尝试编写一个函数来返回回归系数和标准误差,因为我需要运行大量回归。 数据可能如下所示

library(tidyverse)
library(fixest)
library(broom)
data<-tibble(Date = c("2020-01-01","2020-01-01","2020-01-01","2020-01-01","2020-02-01","2020-02-01","2020-02-01","2020-02-01"),
         Card = c(1,2,3,4,1,2,3,4),
         A = rnorm(8),
         B = rnorm(8),
         C = rnorm(8)
         )

我目前的代码如下

estimation_fun <- function(col1,col2,df) {

  regression<-feols(df[[col1]] ~ df[[col2]] | Card + Date, df)

  est =tidy(regression)$estimate
  se = tidy(regression)$std.error

  output <- list(est,se)
  return(output)

}
estimation_fun("A","B",example)

但是,它不起作用。我猜它与 feols 中的列名有关,因为我可以使它适用于 lm()

【问题讨论】:

    标签: r regression


    【解决方案1】:

    Ronak 的权利:只能使用由变量名组成的公式。

    由于fixest 0.10.0,您可以使用点方括号运算符来做到这一点。请参阅xpd 中的公式操作帮助页面。

    只需更改代码中的一行即可使其正常工作:

    estimation_fun <- function(lhs, rhs, df) {
      # lhs must be of length 1 (otherwise => not what you'd want)
      # rhs can be a vector of variables
      regression <- feols(.[lhs] ~ .[rhs] | Card + Date, df)
      
      # etc...
    }
    
    # Example of how ".[]" works: 
    
    lhs = "A"
    rhs = c("B", "C")
    feols(.[lhs] ~ .[rhs], data)
    #> OLS estimation, Dep. Var.: A
    #> Observations: 8 
    #> Standard-errors: IID 
    #>              Estimate Std. Error   t value Pr(>|t|) 
    #> (Intercept)  0.375548   0.428293  0.876849  0.42069 
    #> B           -0.670476   0.394592 -1.699164  0.15004 
    #> C            0.177647   0.537452  0.330536  0.75440 
    #> ---
    #> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    #> RMSE: 0.737925   Adj. R2: 0.183702
    

    顺便说一句,我建议使用内置的多重估算工具(请参阅帮助here),因为估算速度会大大提高。

    更新

    所有组合都可以用一行代码估算出来:

    # All combinations at once
    est_all = feols(c(A, B, C) ~ sw(A, B, C) | Card + Date, data)
    

    coefs/SEs 的提取可以用另一行来完成:

    # Coef + SE // see doc for summary.fixest_multi
    coef_se_all = summary(est_all, type = "se_long")
    coef_se_all
    #>    lhs rhs type          A          B          C
    #> 1    A   A coef  1.0000000         NA         NA
    #> 2    A   A   se        NaN         NA         NA
    #> 3    A   B coef         NA  0.8204932         NA
    #> 4    A   B   se         NA  1.1102853         NA
    #> 5    A   C coef         NA         NA -0.7889534
    #> 6    A   C   se         NA         NA  0.3260451
    #> 7    B   A coef  0.2456443         NA         NA
    #> 8    B   A   se  0.2314143         NA         NA
    #> 9    B   B coef         NA  1.0000000         NA
    #> 10   B   B   se         NA        NaN         NA
    #> 11   B   C coef         NA         NA -0.1977089
    #> 12   B   C   se         NA         NA  0.3335988
    #> 13   C   A coef -0.4696954         NA         NA
    #> 14   C   A   se  0.3858851         NA         NA
    #> 15   C   B coef         NA -0.3931512         NA
    #> 16   C   B   se         NA  0.8584968         NA
    #> 17   C   C coef         NA         NA  1.0000000
    #> 18   C   C   se         NA         NA        NaN
    

    注意:它需要fixest 0.10.1 或更高版本。

    【讨论】:

    • 谢谢。我的设置需要A~B、A~C、B~A、B~C、C~A、C~B等所有变量对,然后提取系数和标准误。你有这样做的建议吗?
    • 再次感谢。您能否让 est_all 更具重现性,因为我的数据中的列数(A、B、C、...)确实很大。也许像 cols
    • 顺便说一句,fixst 0.10.1 开发版吗?
    • 0.10.1 确实是开发版。尼克,拜托,你不觉得你在浪费我们的时间吗?两个答复都是对您原始问题的回答。您可能会考虑雇用某人。
    • 好的。对不起。无论如何,谢谢!
    【解决方案2】:

    feols 函数需要一个公式对象。您可以使用paste0/sprintf 创建它。

    estimation_fun <- function(col1,col2,df) {
      
      regression<-feols(as.formula(sprintf('%s ~ %s | Card + Date', col1, col2)), df)
      
      est =tidy(regression)$estimate
      se = tidy(regression)$std.error
      
      output <- list(est,se)
      return(output)
      
    }
    
    estimation_fun("A","B",data)
    
    #[[1]]
    #[1] -0.1173276
    #attr(,"type")
    #[1] "Clustered (Card)"
    
    #[[2]]
    #[1] 1.083011
    #attr(,"type")
    #[1] "Clustered (Card)"
    

    将此应用于您可能执行的每一对变量 -

    cols <- names(data)[-(1:2)]
    
    do.call(rbind, combn(cols, 2, function(x) {
      data.frame(cols = paste0(x, collapse = '-'), 
                 t(estimation_fun(x[1],x[2],data)))
    }, simplify = FALSE))
    
       cols         X1        X2
    #1  A-B -0.1173276  1.083011
    #2  A-C -0.1117691 0.5648162
    #3  B-C -0.3771884 0.1656587
    

    【讨论】:

    • 非常感谢!您能否告诉我如何将此函数应用于所有列对,就像在 stackoverflow.com/questions/69511160/… 中一样,除了现在我不需要输出前面的“日期”,因为我不需要 group_split(Date)。
    • 更新了答案以将函数应用于每个组合。
    • 谢谢!你能把它做成“tidyverse”风格吗?想让代码保持一致。
    • 理想情况下,我需要所有配对(即 A-B、B-A 在此设置中不同)
    • 类似于您在上一个问题中的回答: tmp % group_split(time) %>% map_df(~cbind(time = .x$time[1], tmp, value = apply(tmp, 1, function(x) fun(.x[[x[1]]] , .x[[x[2]]]))))
    猜你喜欢
    • 2021-12-12
    • 2019-01-28
    • 1970-01-01
    • 2015-09-12
    • 2022-07-27
    • 2018-10-10
    • 2021-07-09
    • 2017-07-28
    相关资源
    最近更新 更多