3

I have a problem with my stargazer output in R.

Here's my original dataframe:

Rank  p     LMax   10%   5%  1%   
var1  0.427  24.25 21.8 27.4 31.5
var2  0.228  7.23  11.5 12.2 16.7

What stargazer creates:

stargazer(data_summary, summary=FALSE, digits = 3)

Rank  p      LMax   10%    5%     1%   
var1  0.427  24.250 21.800 27.400 31.500
var2  0.248  7.230  11.500 12.200 16.700

It's important to keep the three digits for p but remain 2 digits for the others. digits = 2 doesn't solve the problem, as p then only has two digits.

The desired output:

Rank  p      LMax   10%    5%     1%   
var1  0.427  24.25 21.80 27.40 31.50
var2  0.248  7.23  11.50 12.20 16.70

Any idea how to solve this?

RPacker
  • 183
  • 1
  • 3
  • 10
  • If the columns are numeric you can go with: `dat[3:5] <- round(dat[3:5], 2)` – Rentrop Oct 13 '16 at 08:20
  • I know that I can manipulate the dataframe but somehow stargazer can only apply one decimal structure to all values? I wish it would simply print the dataframe, as it is. – RPacker Oct 13 '16 at 08:26
  • If you want the original dataframe to be printed "as it is", why not just use `digits=NA`? According to stargazer manual this should forgo rounding completely. I trust omitting the whole digits argument altogether might have the same outcome. – Olli J Oct 13 '16 at 08:34
  • 1
    @OlliJ, seen that but it responds "Error in paste(first.part, .format.decimal.character, decimal.part, sep = "") : object 'decimal.part' not found" – RPacker Oct 13 '16 at 16:08
  • Same question here! – RPacker Oct 16 '16 at 09:35

2 Answers2

2

A hacky solution is to convert your dataframe into character vectors, each with the appropriate number of decimal points.

data_summary <- read.table(text = "
Rank  p     LMax   p10   p5  p1   
var1  0.427  24.25 21.8 27.4 31.5
var2  0.228  7.23  11.5 12.2 16.7", header = TRUE, stringsAsFactors = FALSE)

We write an anonymous function that, given an integer x (number of decimal points) and a numeric vector y, returns a character vector:

out <- mapply(function(x, y) sprintf(sprintf("%%.0%if", y), x), 
  data_summary[-1],
  c(3, 2, 2, 2, 2))
#      p       LMax    p10     p5      p1     
# [1,] "0.427" "24.25" "21.80" "27.40" "31.50"
# [2,] "0.228" "7.23"  "11.50" "12.20" "16.70"

Bind the values to row labels:

data_summary_out <- as.data.frame(cbind(data_summary[, 1], out))
data_summary_out <- setNames(data_summary_out, names(data_summary))

stargazer now gives you your desired output:

library(stargazer)
stargazer(data_summary_out,
          type = "text",
          summary = FALSE,
          digits = NA)
# ====================================
#   Rank   p   LMax   p10   p5    p1  
# ------------------------------------
# 1 var1 0.427 24.25 21.80 27.40 31.50
# 2 var2 0.228 7.23  11.50 12.20 16.70
# ------------------------------------
Weihuang Wong
  • 12,868
  • 2
  • 27
  • 48
  • How did you get from `out` to `data_summary_out`? I'm guessing a `bind_cols()`? Thank you for all of this solution, by the way, it's great. – Jeremy K. Aug 21 '19 at 02:13
  • because when I bind_cols() I keep getting an error that `Argument 2 must have names`. I'm trying to copy the names from `out` to `data_summary`, but I'm having a bit of trouble – Jeremy K. Aug 21 '19 at 02:25
  • 1
    I skipped a couple of steps in my answer. Please see edits. – Weihuang Wong Aug 21 '19 at 14:44
0

@weihuangwong's solution is good but could be further distilled. The simple answer is, if your table already has the desired number of significant digits for each column, use the digits = NA argument. So adapting the original example:

stargazer(data_summary, summary=FALSE, digits = NA)

Per stargazer's documentation:

A value of NA indicates that no rounding should be done at all, and that all available decimal places should be reported.

If your columns are not already rounded to the desired number of digits, an alternative to the approaches described so far is you could use a tidyverse approach. Using the original table column labels as an example (but assuming that the columns were not rounded as desired):

library(dplyr)
library(stargazer)

data_summary <- data_summary %>% 
    mutate(across('p'), round, 3)) %>%
    mutate(across('LMax'), round, 2)) %>%
    mutate(across(c('10%', '5%', '1%'), round, 1))
      
stargazer(df, summary = FALSE, digits = NA)