【问题标题】:How to display coefficients in scientific notation with stargazer如何使用 stargazer 以科学计数法显示系数
【发布时间】:2015-10-11 15:51:40
【问题描述】:

我想使用 stargazer 或类似工具在 R 的表格中比较不同模型(lm、glm、plm、pglm)的结果。 但是我找不到以科学计数法显示系数的方法。这是一个问题,因为截距相当大(大约一百万),而其他系数很小(大约 e-7),这会导致大量无用的零,从而使表格更难阅读。

我在这里发现了一个类似的问题:Format model display in texreg or stargazer R as scientific。 但是那里的结果需要重新调整变量,因为我使用计数数据,所以我不想重新调整它。

感谢您的任何建议。

【问题讨论】:

标签: r scientific-notation stargazer coefficients


【解决方案1】:

另一种使用 stargazer 获取科学记数法的可靠方法是破解 digit.separator 参数。此选项允许用户指定分隔小数的字符(在大多数语言环境中通常是句点 .)。我们可以篡改这个参数,将一个唯一可识别的字符串插入到我们希望能够使用正则表达式找到的任何数字中。以这种方式搜索数字的优点是我们只能找到与 stargazer 输出中的数值相对应的数字。 IE。不可能同时匹配作为变量名称一部分的数字(例如 X_12345)或作为乳胶格式化代码一部分的数字(例如 \hline \\[-1.8ex])。在下文中,我使用字符串::::,但我们在表中其他地方找不到的任何唯一字符串(例如哈希)都可以。最好避免在标识符标记中包含任何特殊的正则表达式字符,因为这会使事情稍微复杂化。

使用来自this other answer 的示例模型m1

mark  = '::::'
star = stargazer(m1, header = F, decimal.mark  = mark, digit.separator = '')

replace_numbers = function(x, low=0.01, high=1e3, digits = 3, scipen=-7, ...) {
  x = gsub(mark,'.',x)
  x.num = as.numeric(x)
  ifelse(
    (x.num >= low) & (x.num < high), 
    round(x.num, digits = digits), 
    prettyNum(x.num, digits=digits, scientific = scipen, ...)
  )
}    

reg = paste0("([0-9.\\-]+", mark, "[0-9.\\-]+)")
cat(gsubfn(reg, ~replace_numbers(x), star), sep='\n')

更新 如果要确保在科学记数法中保留尾随零,那么我们可以使用sprintf 而不是 prettyNum。

像这样

replace_numbers = function(x, low=0.01, high=1e3, digits = 3) {
  x = gsub(mark,'.',x)
  x.num = as.numeric(x)
  form = paste0('%.', digits, 'e')
  ifelse(
    (abs(x.num) >= low) & (abs(x.num) < high), 
    round(x.num, digits = digits), 
    sprintf(form, x.num) 
  )
}

【讨论】:

  • 我喜欢这个答案,因为它明确说明了如何不转换中等值,而只转换极端值。我遇到的一个问题是回归伴随着 coef 的 10^-8,所以我需要输入很多数字,所以一切都不会变成 0。这很好,但是最后的 R^2 看起来像.0131575939。有没有办法将所有未转换的标记四舍五入到最接近的千分之一?
  • 好点@wolfsatthedoor - 我将它编辑为在中等值上使用round,以便您也可以在这些值上指定数字。这是否符合您的要求?
  • 为了安全起见,我给了你赏金,让我现在检查一下,很好的答案。我预测随着时间的推移,随着学者转向集成降价文档,这将是一个更受关注的问题!
  • 您能更具体地解释一下 scipen = -7 的作用吗?由于某种原因,四舍五入也有效,但像 .003 这样的数字没有被转换为科学记数法
  • 抱歉 - 在此版本中忘记将 scipen 传递给 PrettyNum。现已更正。基本上scipen 是科学表示法与标准表示法之间的位数差异,以便首选科学表示法。更小(更负)的值会更积极地使用科学记数法。
【解决方案2】:

可能值得向包维护者提出功能请求以包含此选项。

与此同时,您可以自动神奇地用科学记数法替换输出中的数字。替换数字时需要注意一些事项。重要的是不要重新格式化作为乳胶编码一部分的数字。此外,请注意不要替换作为变量名一部分的字符。例如,Sepal.Width 中的 . 很容易被正则表达式误认为是数字。以下代码应处理最常见的情况。但是,例如,如果有人调用他们的变量X_123456789,它可能会将其重命名为X_1.23e+09,具体取决于 scipen 设置。所以需要一些谨慎,并且可能需要在 stargazer 包中实施更强大的解决方案。

这是一个用于演示的示例观星表(无耻地从@mathematical.coffee 复制):

library(stargazer)
library(gsubfn)
m1 <- lm(Sepal.Length ~ Petal.Length*Sepal.Width,
  transform(iris, Sepal.Length = Sepal.Length+1e6,
    Petal.Length=Petal.Length*10, Sepal.Width=Sepal.Width*100))    
star = stargazer(m1, header = F, digit.separator = '')

现在是一个帮助函数来重新格式化数字。您可以使用 digits 和 scipen 参数来控制输出格式。如果您想更频繁地强制使用科学格式,请使用更小(更负面)的 scipen。否则,我们可以通过使用更大的scipen 让它自动使用科学格式,仅用于非常小的或大的数字。 cutoff 参数用于防止重新格式化仅由几个字符表示的数字。

replace_numbers = function(x, cutoff=4, digits=3, scipen=-7) {
  ifelse(nchar(x) < cutoff, x, prettyNum(as.numeric(x), digits=digits, scientific=scipen))
}

然后使用 gsubfn::gsubfn 将其应用于观星器输出

gsubfn("([0-9.]+)", ~replace_numbers(x), star)

【讨论】:

  • @dww 也存在问题,目前的答案是它不能完全让您使用正确的科学记数法,即 X.Ye+(Z) 。上面的输出显示了这个问题,你知道我的意思吗?
  • 不确定我是否完全遵循。你的意思是你想要像例如1.5 x 10$^3$ 而不是 1.5e+03?
  • 不,我的意思是,1e+06 应该是 1.2e+06 或其他。小数点应该一致。您不希望下一行,例如 8.44e-01 和 8.4e-01。您需要 8.44e-01 然后是 8.40e-01(如果是这样的话)。 (上面的 R^2 示例)
  • 好的 - 我和你在一起。我使用使用sprintf 而不是prettyNum 的版本编辑了另一个答案(有赏金的答案)。这允许人们在科学记数法中始终具有相同数量的数字(保留任何尾随零)。如果需要,同样的更改也可以应用于此版本。
【解决方案3】:

这是一个可重现的例子:

m1 <- lm(Sepal.Length ~ Petal.Length*Sepal.Width,
         transform(iris, Sepal.Length = Sepal.Length+1e6,
                   Petal.Length=Petal.Length*10, Sepal.Width=Sepal.Width*100))
# Coefficients:
#              (Intercept)              Petal.Length               Sepal.Width  Petal.Length:Sepal.Width  
#                1.000e+06                 7.185e-02                 8.500e-03                -7.701e-05  

我不相信stargazer 对此提供了轻松的支持。 您可以尝试其他替代方法,例如 xtableany of the many options here(我还没有全部尝试过)

library(xtable)
xtable(m1, display=rep('g', 5)) # or there's `digits` too; see `?xtable`

或者如果你使用knitrpandoc 我很喜欢pander,它已经有自动科学记数法(注意:这是pandoc 输出,看起来像markdown,而不是tex 输出,然后你编织或pandoc到latex/pdf):

library(pander)
pander(m1)

【讨论】:

  • 好的,谢谢。你知道支持 pglm 模型的包吗?我从您发布的列表中尝试了几个,但到目前为止都不走运。
  • pglm 非常具体。甚至您最初的选择stargazer 也不支持它。我认为您必须自己将其转换为一种不错的格式(例如,转换为数据框,然后使用其中一个为其生成乳胶的包)。
猜你喜欢
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多