diff --git a/src/helper_functions.cpp b/src/helper_functions.cpp index 0ad61ba4b..5819ff867 100644 --- a/src/helper_functions.cpp +++ b/src/helper_functions.cpp @@ -477,6 +477,8 @@ void wide_to_long( auto startcol = start_col; + int32_t in_string_nums = string_nums; + // pointer magic. even though these are extracted, they just point to the // memory in the data frame Rcpp::CharacterVector zz_row_r = Rcpp::as(zz["row_r"]); @@ -514,7 +516,7 @@ void wide_to_long( int8_t vtyp = (int8_t)vtyps[i]; // if colname is provided, the first row is always a character - if (ColNames & (j == 0)) vtyp = character; + if (ColNames && j == 0) vtyp = character; std::string vals = Rcpp::as(cvec[j]); std::string row = std::to_string(startrow); @@ -524,8 +526,13 @@ void wide_to_long( if (ref_str.compare("0") == 0) ref_str = col + row; - // factors can be numeric or string or both - if (vtyp == factor) string_nums = true; + // factors can be numeric or string or both. tables require the + // column name to be character and once we have overwritten for + // a factor, we have to reset string_nums. + if (!(ColNames && j == 0) && vtyp == factor) + string_nums = 1; + else + string_nums = in_string_nums; // create struct celltyp cell; diff --git a/tests/testthat/test-tables.R b/tests/testthat/test-tables.R index 07f57bc3e..c4a569f91 100644 --- a/tests/testthat/test-tables.R +++ b/tests/testthat/test-tables.R @@ -203,3 +203,23 @@ test_that("updating table works", { expect_equal(got, "A1:J4") }) + +test_that("writing table headers with factor variables works", { + df <- data.frame( + fct = structure( + 1:2, + levels = c( + "one", + "two" + ), + class = "factor"), + `1` = 1:2, + check.names = FALSE + ) + + wb <- wb_workbook()$add_worksheet()$add_data_table(x = df) + + exp <- "1" + got <- wb$worksheets[[1]]$sheet_data$cc$is[[2]] + expect_equal(exp, got) +})