R中使用logitmfx计算鲁棒的聚类标准误差时出错

4

我希望运行一个logit回归,预测家庭大小和年龄的平均边际效应,以及二元指标(个人是否移民、是否有健康保险或抽烟)对发生高血压概率的影响。

这些数据来自于集群调查,并且我希望在输出中包含稳健的集群标准误差。

但是当我添加代码以包括稳健的集群SE时,我收到一个错误,指出我的回归变量不再被找到,我不确定原因。任何建议都将不胜感激!谢谢。

AGE       IMMIGRANT     FAMSIZE     HLTH_INS    HYPERTEN   SMOKE    PSU
<int>       <dbl>         <int>       <dbl>       <dbl>     <dbl>  <int>
40           0              2          1            0         0      2
23           0              2          1            0         0      1
24           0              2          1            0         0      2
18           0              3          1            1         0      2
30           0              2          1            0         0      2
33           1              6          0            0         0      1

#or if this is an easier output to reproduce:
structure(list(AGE = c(40L, 23L, 24L, 18L, 30L, 33L, 32L, 63L, 
22L, 24L), IMMIGRANT = c(0, 0, 0, 0, 0, 1, 0, 0, 0, 1), FAMSIZE = c(2L, 
2L, 2L, 3L, 2L, 6L, 2L, 1L, 2L, 1L), HLTH_INS = c(1, 1, 1, 1, 
1, 0, 1, 1, 1, 0), HYPERTEN = c(0, 0, 0, 0, 0, 0, 0, 1, 0, 0), 
    SMOKE = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1), PSU = c(2L, 1L, 
    2L, 2L, 2L, 1L, 2L, 2L, 1L, 2L)), row.names = c(NA, -10L), class = "data.frame")


#The regression works without adjusting for clustered SE 
logit<-logitmfx(HYPERTEN~scale(AGE)+IMMIGRANT+scale(FAMSIZE)+HLTH_INS+
                 SMOKE,data=sample,
                atmean=TRUE,robust=T)


#However, when I add in the code to cluster SE I receive the error: "Error in scale(AGE) : object 'AGE' not found" 
logit<-logitmfx(HYPERTEN~scale(AGE)+IMMIGRANT+scale(FAMSIZE)+HLTH_INS+
                 SMOKE,data=sample,
                atmean=TRUE,robust=T,clustervar1="PSU", clustervar2=NULL,!is.null("PSU")) 
2个回答

5

尝试使用源代码复制函数的步骤时,Steffen Moritz的解决方案应该确实可行。问题出现在首次 logitmfx 立即调用另一个函数 logitmfxest

这个函数具有相同的参数,但它还有以下代码:

if(!is.null(clustervar1)){
    if(is.null(clustervar2)){
      if(!(clustervar1 %in% names(data))){
        stop("clustervar1 not in data.frame object")
      }    
      data = data.frame(model.frame(formula, data, na.action=NULL),data[,clustervar1])
      names(data)[dim(data)[2]] = clustervar1
      data=na.omit(data)
    }
    if(!is.null(clustervar2)){
      if(!(clustervar1 %in% names(data))){
        stop("clustervar1 not in data.frame object")
      }    
      if(!(clustervar2 %in% names(data))){
        stop("clustervar2 not in data.frame object")
      }    
      data = data.frame(model.frame(formula, data, na.action=NULL),
                        data[,c(clustervar1,clustervar2)])
      names(data)[c(dim(data)[2]-1):dim(data)[2]] = c(clustervar1,clustervar2)
      data=na.omit(data)
    }
  }

根据您的情况,以下代码将被激活:

if(!is.null(clustervar1)){
    if(is.null(clustervar2)){  
      data = data.frame(model.frame(formula, data, na.action=NULL),data[,clustervar1])
      names(data)[dim(data)[2]] = clustervar1
      data=na.omit(data)
    }
  }

这将重新定义“data”,使其成为基于model.frame构建的data.frame。但是,模型框架使用您公式中的名称,因此突然第二列被称为scale.AGE.,第三列被称为scale.FAMSIZE.。 由于该函数随后调用广义线性模型,因此这是一个大问题。
fit = glm(formula, data=data, family = binomial(link = "logit"), x=T, 
        start = start, control = control) 

在这里,它使用了包含 scale(AGE) 和 scale(FAMSIZE) 的原始公式,但是应用了新的数据帧并更改列名。

因此,在输入之前进行缩放应该可以解决问题。并且正如 Steffen 提到的,任何其他功能都会导致相同的错误,因为当调用 model.frame 时它们会产生类似的列重命名。


1
非常好的分析!可惜这个包没有 GitHub 页面来提出问题,他们可能可以在下一个版本中花点力气解决这个问题。 - Steffen Moritz
@SteffenMoritz 同意。可以找到作者的电子邮件,但直接给他写信可能会有点冒犯。 - Qwethm
@Qwethm谢谢你这么详尽的解释!我非常感激。现在代码可以运行了。 - juliah0494

4

奇怪的是,无法再识别formula中的函数。

如果你移除scale,它就能正常工作。而且其他函数如log()也似乎不起作用。

你可以尝试先计算scale(AGE),然后就不需要将它放入公式中了。

可能长这样:

sample$AGE<-scale(sample$AGE)
sample$FAMSIZE<-scale(sample$FAMSIZE)

form <- as.formula(HYPERTEN~AGE+IMMIGRANT+FAMSIZE+HLTH_INS+SMOKE)
#However, when I add in the code to cluster SE I receive the error: "Error in scale(AGE) : object 'AGE' not found"
logit<-logitmfx(form,data=sample,
                atmean=TRUE,robust=T,clustervar1="PSU", clustervar2=NULL)

谢谢@SteffenMoritz!现在一切都正常运行。 - juliah0494
抱歉,我确实有另一个澄清问题,从R文档([https://www.rdocumentation.org/packages/mfx/versions/1.2-2/topics/logitmfx])中我读到,为了有聚类标准误差,我还需要在回归末尾包括`!is.null(clustervar1)`。但是您提供的示例没有包括这个。您发送的内容是否仍在计算聚类SE? - juliah0494
我在文档中没有看到这个,请提供链接好吗?您可能误解了以下内容:“如果同时 robust=TRUE 且 !is.null(clustervar1),该函数将覆盖鲁棒命令并计算聚类标准误差。” 它说 clustervar1 参数不应为 NULL。因为它不是NULL,而是“PSU”。 - Steffen Moritz
哦!我误解了解释,我以为方程式中需要写'!is.null(clustervar1)`。谢谢! - juliah0494
不客气。是的,他们可能可以更清楚地解释这个 :D - Steffen Moritz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接