Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save an R data frame to Excel file with certain cells in bold?

I often write papers with correlation matrices. I would like to be able to export the correlation matrix to Excel in xls or xlsx format. I would also like to format in bold correlations that meet a threshold (e.g., > .2). I was thinking maybe XLConnect might provide the functionality.

In order to make the example simple, assume the data frame is as follows, and assume I want to bold all cells greater than 5.

x <- data.frame(matrix(1:9, nrow = 3))
# > x
#   X1 X2 X3
# 1  1  4  7
# 2  2  5  8
# 3  3  6  9

As an aside, I note that solutions have been proposed for cellbolding for markdown:

  • How to bold a cell in a table (kable) in rmarkdown?
  • Bold formatting for significant values in a Rmarkdown table

I've also found this answer, but it is not a very general solution in that it takes quite a bit to adapt it to the general task of taking a data frame and a formatting rule:

export data frames to Excel via xlsx with conditional formatting

like image 237
Jeromy Anglim Avatar asked Oct 21 '25 08:10

Jeromy Anglim


1 Answers

I created the following function that was adapted from @jota's answer here

xlsx_boldcells <- function(x, matches, file = "test.xlsx", sheetname = "sheet1") {
    # x data.frame or matrix
    # matches: logical data.frame or matrix of the same size indicating which cells to bold
    # copy data frame to work book and load workbook
    require(xlsx)
    write.xlsx(x, file, sheetName=sheetname)
    wb <- loadWorkbook(file)              

    # specify conditional formatting
    # Note: this could be modified to apply different formatting
    # see ?CellStyle
    fo <- Font(wb, isBold = TRUE)  
    cs <- CellStyle(wb, font=fo)  

    # Get cell references
    sheets <- getSheets(wb)               # get all sheets
    sheet <- sheets[[sheetname]]          # get specific sheet
    rows <- getRows(sheet, rowIndex=2:(nrow(x)+1))  # get rows
    cells <- getCells(rows, colIndex = 2:(ncol(x)+1))  

    # Matches to indexes
    indm <- data.frame(which(matches, arr.ind = TRUE, useNames = FALSE)) 
    names(indm) <- c("row", "col")
    # +1 required because row and column names occupy first rows and columns
    indm$index <- paste(indm$row + 1, indm$col + 1, sep = ".")

    # apply cell style
    lapply(indm$index, function(ii) setCellStyle(cells[[ii]],cs))

    # save workbook
    saveWorkbook(wb, file)
}

Thus, it can be applied to proposed problem:

 xlsx_boldcells(x, x > 5)

yielding:

excel sheet with bold

Or it could be applied to the common correlation problem (i.e., bolding large correlations, e.g., greater than .6) as follows:

data(mtcars)
cors <- round(cor(mtcars), 2)
xlsx_boldcells(cors, abs(cors) > .6 & cors!=1, file = "cormatrix.xlsx")

bold cell formatted correlations using xlsx

like image 136
Jeromy Anglim Avatar answered Oct 23 '25 21:10

Jeromy Anglim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!