예제 #1
0
 // -----------------
 inline void incompatible_join_visitor(SEXP left, SEXP right, const std::string& name_left, const std::string& name_right) {
     std::stringstream s ;
     s << "Can't join on '" 
       << name_left 
       << "' x '"
       << name_right
       << "' because of incompatible types (" 
       << get_single_class(left) 
       << "/" 
       << get_single_class(right) 
       << ")" ;
     stop( s.str() ) ;    
 }
예제 #2
0
JoinVisitor* join_visitor(SEXP left, SEXP right, const SymbolString& name_left, const SymbolString& name_right, bool warn_) {
  // handle Date separately
  bool lhs_date = Rf_inherits(left, "Date");
  bool rhs_date = Rf_inherits(right, "Date");

  switch (lhs_date + rhs_date) {
  case 2:
    return date_join_visitor<ACCEPT_NA_MATCH>(left, right);
  case 1:
    stop("cannot join a Date object with an object that is not a Date object");
  case 0:
    break;
  default:
    break;
  }

  bool lhs_time = Rf_inherits(left, "POSIXct");
  bool rhs_time = Rf_inherits(right, "POSIXct");
  switch (lhs_time + rhs_time) {
  case 2:
    return new POSIXctJoinVisitor<ACCEPT_NA_MATCH>(left, right);
  case 1:
    stop("cannot join a POSIXct object with an object that is not a POSIXct object");
  case 0:
    break;
  default:
    break;
  }

  switch (TYPEOF(left)) {
  case CPLXSXP:
  {
    switch (TYPEOF(right)) {
    case CPLXSXP:
      return new JoinVisitorImpl<CPLXSXP, CPLXSXP, ACCEPT_NA_MATCH>(left, right);
    default:
      break;
    }
    break;
  }
  case INTSXP:
  {
    bool lhs_factor = Rf_inherits(left, "factor");
    switch (TYPEOF(right)) {
    case INTSXP:
    {
      bool rhs_factor = Rf_inherits(right, "factor");
      if (lhs_factor && rhs_factor) {
        if (same_levels(left, right)) {
          return new JoinVisitorImpl<INTSXP, INTSXP, ACCEPT_NA_MATCH>(left, right);
        } else {
          if (warn_) Rf_warning("joining factors with different levels, coercing to character vector");
          return new JoinVisitorImpl<STRSXP, STRSXP, ACCEPT_NA_MATCH>(reencode_char(left), reencode_char(right));
        }
      } else if (!lhs_factor && !rhs_factor) {
        return new JoinVisitorImpl<INTSXP, INTSXP, ACCEPT_NA_MATCH>(left, right);
      }
      break;
    }
    case REALSXP:
    {
      if (!lhs_factor && is_bare_vector(right)) {
        return new JoinVisitorImpl<INTSXP, REALSXP, ACCEPT_NA_MATCH>(left, right);
      }
      break;
      // what else: perhaps we can have INTSXP which is a Date and REALSXP which is a Date too ?
    }
    case LGLSXP:
    {
      if (!lhs_factor) {
        return new JoinVisitorImpl<INTSXP, LGLSXP, ACCEPT_NA_MATCH>(left, right);
      }
      break;
    }
    case STRSXP:
    {
      if (lhs_factor) {
        if (warn_) Rf_warning("joining factor and character vector, coercing into character vector");
        return new JoinVisitorImpl<STRSXP, STRSXP, ACCEPT_NA_MATCH>(reencode_char(left), reencode_char(right));
      }
    }
    default:
      break;
    }
    break;
  }
  case REALSXP:
  {
    switch (TYPEOF(right)) {
    case REALSXP:
      return new JoinVisitorImpl<REALSXP, REALSXP, ACCEPT_NA_MATCH>(left, right);
    case INTSXP:
      return new JoinVisitorImpl<REALSXP, INTSXP, ACCEPT_NA_MATCH>(left, right);
    default:
      break;
    }

  }
  case LGLSXP:
  {
    switch (TYPEOF(right)) {
    case LGLSXP:
      return new JoinVisitorImpl<LGLSXP, LGLSXP, ACCEPT_NA_MATCH> (left, right);
    case INTSXP:
      return new JoinVisitorImpl<LGLSXP, INTSXP, ACCEPT_NA_MATCH>(left, right);
    case REALSXP:
      return new JoinVisitorImpl<LGLSXP, REALSXP, ACCEPT_NA_MATCH>(left, right);
    default:
      break;
    }
    break;
  }
  case STRSXP:
  {
    switch (TYPEOF(right)) {
    case INTSXP:
    {
      if (Rf_inherits(right, "factor")) {
        if (warn_) Rf_warning("joining character vector and factor, coercing into character vector");
        return new JoinVisitorImpl<STRSXP, STRSXP, ACCEPT_NA_MATCH>(reencode_char(left), reencode_char(right));
      }
      break;
    }
    case STRSXP:
    {
      return new JoinVisitorImpl<STRSXP, STRSXP, ACCEPT_NA_MATCH>(reencode_char(left), reencode_char(right));
    }
    default:
      break;
    }
    break;
  }
  default:
    break;
  }

  stop("Can't join on '%s' x '%s' because of incompatible types (%s / %s)",
       name_left.get_utf8_cstring(), name_right.get_utf8_cstring(), get_single_class(left), get_single_class(right)
      );
  return 0;
}
예제 #3
0
파일: join.cpp 프로젝트: kbroman/dplyr
 // -----------------
 inline void incompatible_join_visitor(SEXP left, SEXP right, const std::string& name_left, const std::string& name_right) {
     stop( "Can't join on '%s' x '%s' because of incompatible types (%s / %s)", 
         name_left, name_right, get_single_class(left), get_single_class(right) 
     ) ;    
 }