在texreg或stargazer中以科学计数法显示格式模型

9

我刚刚运行了一个统计模型,希望使用stargazer将模型结果显示为表格。然而,大数字显示完整。

fit2<-lm(A~B,data=C)
stargazer(fit2,type="text")

使用此表作为结果

===================================================
                      Dependent variable:      
                -------------------------------
                               A               
---------------------------------------------------
B                               -0.599             
                                (1.698)            
                          32,126,391.000         
                         (24,004,268.000)        

---------------------------------------------------
 Observations                       5               
R2                               0.040             
Adjusted R2                     -0.280             
Residual Std. Error   31,217,258.000 (df = 3e+00)  
F Statistic            0.124 (df = 1e+00; 3e+00)   
===================================================
Note:               *p<1e-01; **p<5e-02; ***p<1e-02

我该如何将大数字显示为科学计数法,例如:3.12e+07呢?

我尝试过:

options("scipen"=-20,"digit"=2)
fit1<-format(lm(A~B,data=C),scientific=T)

然而,这会导致模型摘要失真,并以单行显示。请问有哪些最佳方式来格式化数字并保留表格结构?

                   CO          NO2        SM
Dec 2004 2.750000e+18 1.985136e+15 0.2187433
Jan 2005 2.980000e+18 2.144211e+15 0.1855678
Feb 2005 2.810000e+18 1.586491e+15 0.1764805
Dec 2005 3.010000e+18 1.755409e+15 0.2307153
Jan 2006 3.370000e+18 2.205888e+15 0.2046671
Feb 2006 3.140000e+18 2.084682e+15 0.1834232
Dec 2006 2.940000e+18 1.824735e+15 0.1837391
Jan 2007 3.200000e+18 2.075785e+15 0.1350665
Feb 2007 3.060000e+18 1.786481e+15 0.1179924
Dec 2007 2.750000e+18 1.645800e+15 0.2037340
Jan 2008 3.030000e+18 1.973517e+15 0.1515871
Feb 2008 3.040000e+18 1.753803e+15 0.1289968
Dec 2008 2.800000e+18 1.649315e+15 0.1968024
Jan 2009 3.090000e+18 1.856762e+15 0.1630173
Feb 2009 2.880000e+18 1.610011e+15 0.1446938
Dec 2009 2.660000e+18 1.562971e+15 0.1986012
Jan 2010 2.864333e+18 1.733843e+15 0.1559205
Feb 2010 2.881474e+18 1.469982e+15 0.1397536
Dec 2010 2.730000e+18 1.652751e+15 0.2129476
Jan 2011 3.030000e+18 1.862774e+15 0.1681295
Feb 2011 2.850000e+18 1.658988e+15 0.1531579

这是实际数据的样本: - Joke O.
1
我简直不敢相信没有办法让stargazer为回归分析做科学计数法! - wolfsatthedoor
3个回答

3

为了实现这一点,您可以编写自己的函数,将大量数字放入科学计数法中。

首先,加载stargazer 包:

library(stargazer)

接下来,创建大量数据以进行示例:

set.seed(1)

C <- data.frame("A" = rnorm(10000, 30000, 10000),
                "B" = rnorm(10000, 7500, 2500))

拟合模型并将 stargazer 结果表存储在一个对象中:

fit2 <- lm(A ~ B, data = C) 

myResults <- stargazer(fit2, type = "text")

创建一个函数,将stargazer表中的大数字转换为科学计数法。(这不是非常灵活的,但可以通过简单的修改来实现。目前仅适用于1,000-99,999)

fixNumbers <- function(stargazer.object){

  so <- stargazer.object
  rows <- grep(".*[\\d+],[\\d+].*", so, perl = T)
  for(row in rows){

    # Get number and format into scientific notation
    number <- as.numeric(sub(".*([0-9]{1,2}),([0-9]+\\.?[0-9]*).*", "\\1\\2", so[row], perl = T))
    formatted_num <- sprintf("%.2e", number)
    so[row] <- sub("(.*)[0-9]{1,2},[0-9]+\\.?[0-9]*(.*)", paste0("\\1", formatted_num, "\\2"), so[row], perl = T)
  }

  # Print result
  for(i in 1:length(so)){
    cat(so[i], "\n")
  }
}

给你的 stargazer 对象添加新函数 (fixNumbers):

fixNumbers(myResults)

-- 这是所有代码的整体代码:--

library(stargazer)

set.seed(1)

C <- data.frame("A" = rnorm(10000, 30000, 10000),
                "B" = rnorm(10000, 7500, 2500))

fit2 <- lm(A ~ B, data = C) 

myResults <- stargazer(fit2, type = "text")

fixNumbers <- function(stargazer.object){

  so <- stargazer.object
  rows <- grep(".*[\\d+],[\\d+].*", so, perl = T)
  for(row in rows){

    # Get number and format into scientific notation
    number <- as.numeric(sub(".*([0-9]{1,2}),([0-9]+\\.?[0-9]*).*", "\\1\\2", so[row], perl = T))
    formatted_num <- sprintf("%.2e", number)
    so[row] <- sub("(.*)[0-9]{1,2},[0-9]+\\.?[0-9]*(.*)", paste0("\\1", formatted_num, "\\2"), so[row], perl = T)
  }

  # Print result
  for(i in 1:length(so)){
    cat(so[i], "\n")
  }
}

fixNumbers(myResults)

3

借鉴Adam K的想法,但是使用更加优化的正则表达式(并利用向量化,在R中这是个好主意):

fit2<-lm(CO~NO2,data=df)
test <- stargazer(fit2,type="text",)

这是一个两行的正则表达式:你需要找到数字(此处为五个以上的数字),它们是由数字、逗号和小数点组成的字符串。

m <- gregexpr("([0-9\\.,]{5,})", test)

你需要对其应用一个转换函数(这里省略逗号,将其转为数字,并以科学计数法显示,保留2位小数。你还可以考虑使用formatC,该函数提供了很多可能性):

f = function(x){
  sprintf("%.2e",as.numeric( gsub(",","",x)))
}

你需要使用regmatches函数将其应用于你的正则表达式

regmatches(test, m) <- lapply(regmatches(test, m), f)
test


 [1] ""                                                           
 [2] "========================================================"   
 [3] "                            Dependent variable:         "   
 [4] "                    ------------------------------------"   
 [5] "                                     CO                 "   
 [6] "--------------------------------------------------------"   
 [7] "NO2                              6.26e+02**              "  
 [8] "                                 (2.41e+02)              "  
 [9] "                                                        "   
[10] "Constant              1.81e+18***  "                        
[11] "                       (4.62e+17)    "                      
[12] "                                                        "   
[13] "--------------------------------------------------------"   
[14] "Observations                         10                 "   
[15] "R2                                 4.58e-01                "
[16] "Adjusted R2                        3.90e-01                "
[17] "Residual Std. Error 1.57e+17 (df = 8)"                      
[18] "F Statistic                 6.76e+00** (df = 1; 8)         "
[19] "========================================================"   
[20] "Note:                        *p<0.1; **p<0.05; ***p<0.01"   

要获得与原始输出相同的结果:
print(as.data.frame(test),quote = F,row.names = FALSE)



                                                       test

    ========================================================
                                Dependent variable:         
                        ------------------------------------
                                         CO                 
    --------------------------------------------------------
   NO2                              6.26e+02**              
                                    (2.41e+02)              

                         Constant              1.81e+18***  
                                              (4.62e+17)    

    --------------------------------------------------------
    Observations                         10                 
 R2                                 4.58e-01                
 Adjusted R2                        3.90e-01                
                       Residual Std. Error 1.57e+17 (df = 8)
 F Statistic                 6.76e+00** (df = 1; 8)         
    ========================================================
    Note:                        *p<0.1; **p<0.05; ***p<0.01

数据:

df <- read.table(text  = "
CO NO2 SM
 2.750000e+18 1.985136e+15 0.2187433
 2.980000e+18 2.144211e+15 0.1855678
 2.810000e+18 1.586491e+15 0.1764805
 3.010000e+18 1.755409e+15 0.2307153
 3.370000e+18 2.205888e+15 0.2046671
 3.140000e+18 2.084682e+15 0.1834232
 2.940000e+18 1.824735e+15 0.1837391
 3.200000e+18 2.075785e+15 0.1350665
 3.060000e+18 1.786481e+15 0.1179924
 2.750000e+18 1.645800e+15 0.2037340",header = T)

-4

问题不在于这些包无法显示科学计数法,而是你的自变量处于极小的尺度上。在将其用于模型之前,你应该通过乘以某个常数来重新调整它们的值。例如,当你处理人的大小时,如果单位是公里,你可能需要将其重新调整为米或厘米。这样做会使表格比使用科学计数法更易读。

考虑以下示例:

a <- c(4.17, 5.58, 5.18, 6.11, 4.50, 4.61, 5.17, 4.53, 5.33, 5.14)
b <- c(0.00020, 0.00024, 0.00024, 0.00026, 0.00021, 0.00022, 0.00023, 
    0.00022, 0.00023, 0.00022)
model.1 <- lm(a ~ b)

接下来,使用texreg创建你的表格:
library("texreg")
screenreg(model.1)

这将产生以下表格:

=========================
             Model 1     
-------------------------
(Intercept)     -2.27 *  
                (0.94)   
b            32168.58 ***
             (4147.00)   
-------------------------
R^2              0.88    
Adj. R^2         0.87    
Num. obs.       10       
=========================
*** p < 0.001, ** p < 0.01, * p < 0.05

所以这些系数相当大。让我们试一下使用 stargazer 来进行同样的操作:

library("stargazer")
stargazer(model.1, type = "text")

结果表格:

===============================================
                        Dependent variable:    
                    ---------------------------
                                 a             
-----------------------------------------------
b                          32,168.580***       
                            (4,146.999)        

Constant                     -2.270**          
                              (0.944)          

-----------------------------------------------
Observations                    10             
R2                             0.883           
Adjusted R2                    0.868           
Residual Std. Error       0.212 (df = 8)       
F Statistic            60.172*** (df = 1; 8)   
===============================================
Note:               *p<0.1; **p<0.05; ***p<0.01

同样的问题:大系数。现在重新调整您的原始变量 b 并重新计算模型:

b <- b * 10000
model.2 <- lm(a ~ b)

texreg再试一次:

screenreg(model.2)

======================
             Model 1  
----------------------
(Intercept)  -2.27 *  
             (0.94)   
b             3.22 ***
             (0.41)   
----------------------
R^2           0.88    
Adj. R^2      0.87    
Num. obs.    10       
======================
*** p < 0.001, ** p < 0.01, * p < 0.05

而且使用 stargazer

stargazer(model.2, type = "text")

===============================================
                        Dependent variable:    
                    ---------------------------
                                 a             
-----------------------------------------------
b                            3.217***          
                              (0.415)          

Constant                     -2.270**          
                              (0.944)          

-----------------------------------------------
Observations                    10             
R2                             0.883           
Adjusted R2                    0.868           
Residual Std. Error       0.212 (df = 8)       
F Statistic            60.172*** (df = 1; 8)   
===============================================
Note:               *p<0.1; **p<0.05; ***p<0.01

现在系数看起来更好,您不需要使用科学计数法。


嗨,spammerslammer,感谢您的回答。但是我正在处理的实际两个变量是大气数据,它们是10x18和10x15的倍数。有没有办法在latex中将其四舍五入,以便可以显示为:4x10的15次方,而不是完整长度? - Joke O.
那么是什么阻止你重新调整它们的大小?我的意思是,为什么不能将它们除以10x18并相应地更改解释?(出于好奇:测量单位是什么?) - Philip Leifeld
它以分子/cm²为单位。 - Joke O.
那么,将其表示为每平方埃的分子数,应该是您的值乘以10的16次方,我想(但不确定)。 - Philip Leifeld

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