r-lib / vctrs
Showing 3 of 7 files from the diff.

@@ -10,6 +10,9 @@
Loading
10 10
#' `nan_distinct = FALSE`, `NaN` values are given the same rank as `NA`,
11 11
#' otherwise they are given a rank that differentiates them from `NA`.
12 12
#'
13 +
#' For data frames, `na_propagate = TRUE` will propagate a missing value if
14 +
#' any row is incomplete, as determined by [vec_detect_complete()].
15 +
#'
13 16
#' Like [vec_order_radix()], ordering is done in the C-locale. This can affect
14 17
#' the ranks of character vectors, especially regarding how uppercase and
15 18
#' lowercase letters are ranked. See the Details section of [vec_order_radix()]

@@ -1,5 +1,4 @@
Loading
1 -
#include <rlang.h>
2 -
#include "vctrs.h"
1 +
#include "complete.h"
3 2
#include "equal.h"
4 3
#include "type-data-frame.h"
5 4
@@ -32,8 +31,6 @@
Loading
32 31
  return vec_locate_complete(x);
33 32
}
34 33
35 -
static SEXP vec_detect_complete(SEXP x);
36 -
37 34
static
38 35
SEXP vec_locate_complete(SEXP x) {
39 36
  SEXP where = PROTECT(vec_detect_complete(x));
@@ -51,7 +48,7 @@
Loading
51 48
52 49
static inline void vec_detect_complete_switch(SEXP x, R_len_t size, int* p_out);
53 50
54 -
static
51 +
// [[ include("complete.h") ]]
55 52
SEXP vec_detect_complete(SEXP x) {
56 53
  SEXP proxy = PROTECT(vec_proxy_complete(x));
57 54

@@ -1,6 +1,6 @@
Loading
1 1
#include <rlang.h>
2 2
#include "vctrs.h"
3 -
#include "equal.h"
3 +
#include "complete.h"
4 4
#include "order-radix.h"
5 5
6 6
enum ties {
@@ -48,44 +48,29 @@
Loading
48 48
  r_keep_t pi_x;
49 49
  KEEP_HERE(x, &pi_x);
50 50
51 -
  r_obj* missing = r_null;
52 -
  r_keep_t pi_missing;
53 -
  KEEP_HERE(missing, &pi_missing);
54 -
  int* v_missing = NULL;
55 -
56 -
  r_obj* not_missing = r_null;
57 -
  r_keep_t pi_not_missing;
58 -
  KEEP_HERE(not_missing, &pi_not_missing);
59 -
  int* v_not_missing = NULL;
51 +
  r_obj* complete = r_null;
52 +
  r_keep_t pi_complete;
53 +
  KEEP_HERE(complete, &pi_complete);
54 +
  int* v_complete = NULL;
60 55
61 56
  r_ssize rank_size = size;
62 57
63 58
  if (na_propagate) {
64 -
    // Slice out non-missing values of `x` to rank.
65 -
    // Retain `non_missing` logical vector for constructing `out`.
66 -
    missing = vec_equal_na(x);
67 -
    KEEP_AT(missing, pi_missing);
68 -
    v_missing = r_lgl_begin(missing);
69 -
70 -
    bool any_missing = r_lgl_any(missing);
71 -
72 -
    if (any_missing) {
73 -
      for (r_ssize i = 0; i < size; ++i) {
74 -
        v_missing[i] = !v_missing[i];
75 -
      }
76 -
77 -
      not_missing = missing;
78 -
      KEEP_AT(not_missing, pi_not_missing);
79 -
      v_not_missing = v_missing;
80 -
      missing = NULL;
81 -
      v_missing = NULL;
82 -
83 -
      x = vec_slice(x, not_missing);
59 +
    // Slice out complete values of `x` to rank.
60 +
    // Retain the logical vector for constructing `out`.
61 +
    complete = vec_detect_complete(x);
62 +
    KEEP_AT(complete, pi_complete);
63 +
    v_complete = r_lgl_begin(complete);
64 +
65 +
    bool all_complete = r_lgl_all(complete);
66 +
67 +
    if (all_complete) {
68 +
      na_propagate = false;
69 +
    } else {
70 +
      x = vec_slice(x, complete);
84 71
      KEEP_AT(x, pi_x);
85 72
86 73
      rank_size = vec_size(x);
87 -
    } else {
88 -
      na_propagate = false;
89 74
    }
90 75
  }
91 76
@@ -118,7 +103,7 @@
Loading
118 103
    r_ssize j = 0;
119 104
120 105
    for (r_ssize i = 0; i < size; ++i) {
121 -
      v_out[i] = v_not_missing[i] ? v_rank[j++] : r_globals.na_int;
106 +
      v_out[i] = v_complete[i] ? v_rank[j++] : r_globals.na_int;
122 107
    }
123 108
124 109
    FREE(1);
@@ -126,7 +111,7 @@
Loading
126 111
    out = rank;
127 112
  }
128 113
129 -
  FREE(5);
114 +
  FREE(4);
130 115
  return out;
131 116
}
132 117
@@ -239,19 +224,19 @@
Loading
239 224
240 225
// Treats missing values as `true`
241 226
static inline
242 -
bool r_lgl_any(r_obj* x) {
227 +
bool r_lgl_all(r_obj* x) {
243 228
  if (r_typeof(x) != R_TYPE_logical) {
244 -
    r_stop_internal("r_lgl_any", "`x` must be a logical vector.");
229 +
    r_stop_internal("r_lgl_all", "`x` must be a logical vector.");
245 230
  }
246 231
247 232
  const int* v_x = r_lgl_cbegin(x);
248 233
  r_ssize size = r_length(x);
249 234
250 235
  for (r_ssize i = 0; i < size; ++i) {
251 -
    if (v_x[i]) {
252 -
      return true;
236 +
    if (!v_x[i]) {
237 +
      return false;
253 238
    }
254 239
  }
255 240
256 -
  return false;
241 +
  return true;
257 242
}
Files Coverage
R 87.13%
src 83.22%
Project Totals (184 files) 83.93%
Notifications are pending CI completion. Waiting for GitHub's status webhook to queue notifications. Push notifications now.
1
comment: false
2

3
coverage:
4
  status:
5
    project:
6
      default:
7
        target: auto
8
        threshold: 1%
9
        informational: true
10
    patch:
11
      default:
12
        target: auto
13
        threshold: 1%
14
        informational: true
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading