xlsx icon indicating copy to clipboard operation
xlsx copied to clipboard

trash on appending data frame to sheet with row.names=F

Open step- opened this issue 9 years ago • 2 comments

Update: not a bug, see next comment in thread Update again: I changed my mind, see third comment in thread

CRAN Version: 0.5.7 Published: 2014-08-02 jdk-7u65-linux-x64

This code appends a data frame to an existing workbook sheet, and it works. The first column of the existing sheet consists of excel string cells. The sheet has no row names.

If I change row.names from TRUE to FALSE the data frame is appended without names (1,2,3...), which is correct, but appended data is unconverted, meaning that just two lines are appended: column headers then a line in which each cell consists of a string that represents the R column vector as a string, i.e., "c(1,0,0,1...."

file <- "/tmp/x.xlsx"
wb <- loadWorkbook(gdwb$path)
sheets <- getSheets(wb)
sheet  <- sheets[[1]] # assume there's just one sheet
lastRowNum <- sheet$getLastRowNum()
addDataFrame(
    bookings$df.cooked,
    sheet,
    row.names = TRUE,
    startRow = lastRowNum + 1)  
saveWorkbook(wb, file)

step- avatar Sep 22 '16 13:09 step-

Apparently this issue hasn't much to do with xlsx. I hadn't realized that I was passing a tibble rather than a data frame. Wrapping bookings$df.cooked in as.data.frame() in the code snippet solved the issue.

step- avatar Sep 22 '16 14:09 step-

Actually, I changed my mind about this issue. I think you should be aware of it and possibly modify some of the xlsx code to better work with tibble objects. When I passed write.xlsx a tibble instead of a data frame, it produced an error message

write.xlsx(x, file)

Error in .jcall(cell, "V", "setCellValue", value) : method setCellValue with signature ([D)V not found In addition: Warning message: In if (is.na(value)) { : the condition has length > 1 and only the first element will be used

write.xlsx source code reads

function (x, file, sheetName = "Sheet1", col.names = TRUE, row.names = TRUE, 
    append = FALSE, showNA = TRUE) 
{
    if (!is.data.frame(x)) 
        x <- data.frame(x)

So, it seems that x is converted to a data.frame if it isn't one. Such is not the case here, because a tibble is a data.frame, but it doesn't behave as such to the amount that write.xlsx seems to expect. Hence the error message.

is.data.frame(x)
[1] TRUE
class(x)
[1] "tbl_df"     "tbl"        "data.frame"

Of course all works well when I explicitly convert x to data.frame before calling write.xlsx

write.xlsx(as.data.frame(x), file)

step- avatar Oct 05 '16 11:10 step-