/src/r-source/src/main/split.c
Line | Count | Source |
1 | | /* |
2 | | * R : A Computer Language for Statistical Data Analysis |
3 | | * Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka |
4 | | * Copyright (C) 2006-2025 The R Core Team |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, a copy is available at |
18 | | * https://www.R-project.org/Licenses/ |
19 | | */ |
20 | | |
21 | | #ifdef HAVE_CONFIG_H |
22 | | #include <config.h> |
23 | | #endif |
24 | | |
25 | | #include <Defn.h> |
26 | | #include <Internal.h> |
27 | | #include <R_ext/Itermacros.h> |
28 | | |
29 | | attribute_hidden SEXP do_split(SEXP call, SEXP op, SEXP args, SEXP env) |
30 | 46.1k | { |
31 | 46.1k | SEXP x, f, counts, vec, nm, nmj; |
32 | | |
33 | 46.1k | checkArity(op, args); |
34 | | |
35 | 46.1k | x = CAR(args); |
36 | 46.1k | f = CADR(args); |
37 | 46.1k | if (!isVector(x)) |
38 | 0 | error(_("first argument must be a vector")); |
39 | 46.1k | if (!isFactor(f)) |
40 | 0 | error(_("second argument must be a factor")); |
41 | 46.1k | int nlevs = nlevels(f); |
42 | 46.1k | R_xlen_t nfac = XLENGTH(CADR(args)); |
43 | 46.1k | R_xlen_t nobs = XLENGTH(CAR(args)); |
44 | 46.1k | if (nfac <= 0 && nobs > 0) |
45 | 0 | error(_("group length is 0 but data length > 0")); |
46 | 46.1k | if (nfac > 0 && (nobs % nfac) != 0) |
47 | 0 | warning(_("data length is not a multiple of split variable")); |
48 | 46.1k | nm = getAttrib(x, R_NamesSymbol); |
49 | 46.1k | bool have_names = nm != R_NilValue; // used in split-incl.c |
50 | | |
51 | 46.1k | #ifdef LONG_VECTOR_SUPPORT |
52 | 46.1k | if (IS_LONG_VEC(x)) |
53 | 0 | # define _L_INTSXP_ REALSXP |
54 | 0 | # define _L_INTEG_ REAL |
55 | 0 | # define _L_int_ R_xlen_t |
56 | 46.1k | # include "split-incl.c" |
57 | | |
58 | 46.1k | # undef _L_INTSXP_ |
59 | 46.1k | # undef _L_INTEG_ |
60 | 46.1k | # undef _L_int_ |
61 | 46.1k | else |
62 | 46.1k | #endif |
63 | | |
64 | 46.1k | # define _L_INTSXP_ INTSXP |
65 | 272k | # define _L_INTEG_ INTEGER |
66 | 46.1k | # define _L_int_ int |
67 | 46.1k | # include "split-incl.c" |
68 | | |
69 | 46.1k | # undef _L_INTSXP_ |
70 | 46.1k | # undef _L_INTEG_ |
71 | 46.1k | # undef _L_int_ |
72 | | |
73 | 46.1k | setAttrib(vec, R_NamesSymbol, getAttrib(f, R_LevelsSymbol)); |
74 | 46.1k | UNPROTECT(2); |
75 | 46.1k | return vec; |
76 | 46.1k | } |