R中的十进制数在stargazer中的表示

13

我正在使用R软件包stargazer在LaTeX中生成表格。它运作得很好,但是我无法弄清楚如何正确地格式化我的数字。我希望所有数字都只显示一位小数(例如1.0、0.1、10.5等)。因此,我使用选项digits=1。然而,对于像1这样的精确数字,这会给我1而不是1.0。如何即使对于精确数字也能获得一位小数(1.0而不是1)?

3个回答

10
您可以使用正则表达式在使用stargazer后添加小数位。以下是一个示例。根据您使用stargazer生成的汇总类型,您可能需要稍微更改正则表达式字符串,但由于问题中没有包含最小示例,因此我所能做的最好的就是给出这种方法的通用示例:

使用stargazer后,可以使用正则表达式将小数位添加回来。以下是一个示例。根据您使用stargazer生成的汇总类型,您可能需要稍微更改正则表达式字符串,但由于问题中没有包含最小示例,因此我所能做的最好的就是给出这种方法的通用示例:

star = stargazer(attitude, digits=1, digits.extra=1)
star = gsub("& ([0-9]+) ", "& \\1\\.0 ", star)

cat(star, sep = "\n")

# % Table created by stargazer v.5.2 by Marek Hlavac, Harvard University. E-mail: hlavac at fas.harvard.edu
# % Date and time: Sat, Oct 08, 2016 - 8:11:26 PM
# \begin{table}[!htbp] \centering 
# \caption{} 
# \label{} 
# \begin{tabular}{@{\extracolsep{5pt}}lccccc} 
# \\[-1.8ex]\hline 
# \hline \\[-1.8ex] 
# Statistic & \multicolumn{1}{c}{N} & \multicolumn{1}{c}{Mean} & \multicolumn{1}{c}{St. Dev.} & \multicolumn{1}{c}{Min} & \multicolumn{1}{c}{Max} \\ 
# \hline \\[-1.8ex] 
# rating & 30.0 & 64.6 & 12.2 & 40.0 & 85.0 \\ 
# complaints & 30.0 & 66.6 & 13.3 & 37.0 & 90.0 \\ 
# privileges & 30.0 & 53.1 & 12.2 & 30.0 & 83.0 \\ 
# learning & 30.0 & 56.4 & 11.7 & 34.0 & 75.0 \\ 
# raises & 30.0 & 64.6 & 10.4 & 43.0 & 88.0 \\ 
# critical & 30.0 & 74.8 & 9.9 & 49.0 & 92.0 \\ 
# advance & 30.0 & 42.9 & 10.3 & 25.0 & 72.0 \\ 
# \hline \\[-1.8ex] 
# \end{tabular} 
# \end{table}
在此示例中,模式“& ([0-9]+)”查找“&”后跟一串数字,再跟一个空格。然后用“&”、它找到的相同数字组(使用//1)、一个小数点(//. 因为点必须转义,因为它们是正则表达式中的特殊字符)、一个小数零和一个空格来替换它。
stargazer产生的一些不同的摘要格式可能会有其他需要包含在搜索字符串中的内容,例如紧跟数字的非空格字符(例如逗号)。或者在某些情况下,可能需要替换不是由“&”前导的数字。
无论如何,一般的方法都是相同的。

1
很高兴这有所帮助。顺便说一下,我认为你想要的应该是stargazer的默认行为(或者至少是内置选项)。你可以考虑联系软件包维护人员提出此功能请求。 - dww
这种方法会出现四舍五入错误,例如0.49变成了0.4? - Antti
1
@Antti - 不,这个正常工作。正则表达式不会进行四舍五入。这已经由stargazer执行了。正则表达式所做的只是在stargazer打印例如10.0作为10时,它会添加回小数点以打印10.0。Stargazer将0.49向上舍入,就像它应该做的那样。 - dww
1
为什么不能让星表输出自己完成呢? - wolfsatthedoor
@dww 我想知道你是否能帮忙写一个针对 stargazer 输出的 HTML 的 gsub 函数?输出结果看起来像这样:<td>111</td><td>141.4</td><td>92.2</td><td>14</td>,我想在 111 和 14 后面添加小数点,但不想在 141.4 后面添加。 - Jeremy K.

6
感谢您推动更加集成化的解决方案,wolfsatthedoor。我自己也考虑了很长时间,似乎星座观察者的代码是故意这样编写的。
通过查看源代码,我们可以发现:
trace(stargazer:::.stargazer.wrap, edit = T)

在第4485行左右(根据版本可能会有些许差异)揭示了.summ.stat.publish.statistic检查返回值.is.all.integers.是否为整数。如果是,则最终值将被硬编码成0个数字进行四舍五入。

else if (which.statistic == "median") {
        median.value <- median(temp.var, na.rm = TRUE)
        if (.is.all.integers(temp.var) == FALSE) {
          how.much.to.round <- .format.s.round.digits
        }
        else {
          if (.is.all.integers(median.value) == TRUE) {
            how.much.to.round <- 0
          }
          else {
            how.much.to.round <- 1
          }
        }
        return(.iround(median.value, how.much.to.round))
      }

要更改此行为,您需要将所有how.much.to.round更改为.format.s.round.digits,这是使用数字命令指定的值。您需要针对所有汇总统计信息分别执行此操作,即中位数、最小值、最大值和p,在4510年至4570年之间的行中执行此操作。这还确保了N列不携带不必要的数字。

保存的自定义stargazer函数应按以下方式运作(注意:每次重新启动R-Session时,您都需要重新进行更改 - 您可以通过导出函数来防止此问题):

stargazer((cbind(A = c(1,1,1,1), B = c(3,4,3,3))), summary = T, digits = 2, header = F, type = "text")
# ===================================
# Statistic N Mean St. Dev. Min  Max 
# -----------------------------------
# A         4 1.00   0.00   1.00 1.00
# B         4 3.25   0.50   3.00 4.00
# -----------------------------------

stargazer((cbind(A = c(1,1,1,1), B = c(3,4,3,3))), summary = T, digits = 2, header = F)
# \begin{table}[!htbp] \centering 
#   \caption{} 
#   \label{} 
# \begin{tabular}{@{\extracolsep{5pt}}lccccc} 
# \\[-1.8ex]\hline 
# \hline \\[-1.8ex] 
# Statistic & \multicolumn{1}{c}{N} & \multicolumn{1}{c}{Mean} & \multicolumn{1}{c} {St. Dev.} & \multicolumn{1}{c}{Min} & \multicolumn{1}{c}{Max} \\ 
# \hline \\[-1.8ex] 
# A & 4 & 1.00 & 0.00 & 1.00 & 1.00 \\ 
# B & 4 & 3.25 & 0.50 & 3.00 & 4.00 \\ 
# \hline \\[-1.8ex] 
# \end{tabular} 
# \end{table} 

能否提供另一种功能? - wolfsatthedoor
1
一般而言,是的。但我通常会有一个带有自定义代码的 *.R 文件,然后每次重新启动 R 会话时(这不经常发生),我都会调用 trace(stargazer:::.stargazer.wrap, edit = T) 并将代码从 *.R 文件复制到开放窗口并保存它。就我个人而言,这个小解决方法不值得创建一个定制的软件包并保持其最新状态。您可以在此处找到完整的定制代码:https://github.com/op-two/stargazer_custom/blob/master/wrap_stargazer_customized.R - JNWHH
@JNWHH 谢谢您提供的自定义代码!您知道是否有任何方法可以自动化 trace(stargazer:::.stargazer.wrap, edit =T),以及随后的剪切和粘贴吗? - Jeremy K.
@JNWHH,另外,当我尝试使用您的自定义代码时,我会收到以下错误消息:“deparse可能不完整。在软件包“stargazer(未导出)”中跟踪函数“.stargazer.wrap”[1]“.stargazer.wrap””,并且输出结果没有固定。您知道我可以尝试什么吗? - Jeremy K.

0
(在打开stargazer的跟踪之前)如果您想显示脚本中指定的所有数字,请替换例如:
else if (which.statistic == "min") {
        if (.is.all.integers(temp.var) == FALSE) {
          how.much.to.round <- .format.s.round.digits
        }
        else {
          how.much.to.round <- .format.s.round.digits
        }
        return(.iround(min(temp.var, na.rm = TRUE), 
                       how.much.to.round))
      }

替换为:

   else if (which.statistic == "min") {
        return(.iround(min(temp.var, na.rm = TRUE), .format.s.round.digits))
      }

您可以将min替换为max等。这大约在4530-4576行之间。


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