From 05e35f2058697b6265b0266985106703d2002bc0 Mon Sep 17 00:00:00 2001 From: Anh Le Date: Sun, 2 Oct 2016 14:18:13 -0400 Subject: [PATCH] Resolves #171 When add_row to an empty tibble, all column classes were converted to logical. We fix this by checking whether we're adding to an empty tibble. If yes, we coerce column classes back to the original. --- R/RcppExports.R | 2 +- R/add.R | 11 +++++++++++ src/RcppExports.cpp | 10 +++++----- tests/testthat/helper-data.R | 14 ++++++++++++++ tests/testthat/test-add.R | 5 +++++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/R/RcppExports.R b/R/RcppExports.R index 423023dad..eca794d6c 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -1,4 +1,4 @@ -# This file was generated by Rcpp::compileAttributes +# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 matrixToDataFrame <- function(x) { diff --git a/R/add.R b/R/add.R index a219cbc7b..e1bce8ec9 100644 --- a/R/add.R +++ b/R/add.R @@ -57,6 +57,17 @@ add_row <- function(.data, ..., .before = NULL, .after = NULL) { out <- rbind(.data[indexes, ], df, .data[-indexes, ]) } + # If .data is empty, coerce the out column class to .data class + if (nrow(.data) == 0) { + for (i in 1:ncol(out)) { + if (class(.data[[i]])[1] == "factor") { + out[[i]] <- as.factor(NA) + } else { + class(out[[i]]) <- class(.data[[i]]) + } + } + } + set_class(remove_rownames(out), class(.data)) } diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 73400a730..1b52a2d50 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -1,4 +1,4 @@ -// This file was generated by Rcpp::compileAttributes +// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include @@ -9,10 +9,10 @@ using namespace Rcpp; List matrixToDataFrame(SEXP x); RcppExport SEXP tibble_matrixToDataFrame(SEXP xSEXP) { BEGIN_RCPP - Rcpp::RObject __result; - Rcpp::RNGScope __rngScope; + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< SEXP >::type x(xSEXP); - __result = Rcpp::wrap(matrixToDataFrame(x)); - return __result; + rcpp_result_gen = Rcpp::wrap(matrixToDataFrame(x)); + return rcpp_result_gen; END_RCPP } diff --git a/tests/testthat/helper-data.R b/tests/testthat/helper-data.R index e0eb91365..ea553e612 100644 --- a/tests/testthat/helper-data.R +++ b/tests/testthat/helper-data.R @@ -10,3 +10,17 @@ df_all <- tibble( h = as.list(c(1:2, NA)), i = list(list(1, 2:3), list(4:6), list(NA)) ) + +# An empty data frame with all major types +df_empty = tibble( + a = integer(0), + b = double(0), + c = logical(0), + d = character(0), + e = factor(integer(0)), + f = as.Date(character(0)), + g = as.POSIXct(character(0)), + h = as.list(double(0)), + # i = list(list(integer(0)), list(character(0))), + to_be_added = double(0) +) diff --git a/tests/testthat/test-add.R b/tests/testthat/test-add.R index abda9cd66..bdcdf48de 100644 --- a/tests/testthat/test-add.R +++ b/tests/testthat/test-add.R @@ -96,6 +96,11 @@ test_that("adding to a list column adds a NULL value (#148)", { expect_null(add_row(data_frame(a = as.list(1:3), b = 1:3), b = 4:6)$a[[5]]) }) +test_that("add_row() keeps the class of empty columns", { + new_tibble <- add_row(df_empty, to_be_added = 5) + expect_equal(sapply(df_empty, class), sapply(new_tibble, class)) +}) + # add_column ------------------------------------------------------------ test_that("can add new column", {