The R Project SVN R

Rev

Rev 25281 | Rev 29410 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 25281 Rev 25282
Line 257... Line 257...
257
	v[i] = isDuplicated(x, i, &data);
257
	v[i] = isDuplicated(x, i, &data);
258
 
258
 
259
    return ans;
259
    return ans;
260
}
260
}
261
 
261
 
262
static SEXP duplicated2(SEXP x, HashData *d)
-
 
263
{
-
 
264
    SEXP ans;
-
 
265
    int *h, *v;
-
 
266
    int i, n;
-
 
267
 
-
 
268
    n = LENGTH(x);
-
 
269
    HashTableSetup(x, d);
-
 
270
    PROTECT(d->HashTable);
-
 
271
    ans = allocVector(LGLSXP, n);
-
 
272
    UNPROTECT(1);
-
 
273
    h = INTEGER(d->HashTable);
-
 
274
    v = LOGICAL(ans);
-
 
275
 
-
 
276
    for (i = 0; i < d->M; i++)
-
 
277
	h[i] = NIL;
-
 
278
 
-
 
279
    for (i = 0; i < n; i++)
-
 
280
	v[i] = isDuplicated(x, i, d);
-
 
281
 
-
 
282
    return ans;
-
 
283
}
-
 
284
 
-
 
285
 
-
 
286
/* .Internal(duplicated(x)) [op=0]  and
262
/* .Internal(duplicated(x)) [op=0]  and
287
   .Internal(unique(x))	    [op=1] :
263
   .Internal(unique(x))	    [op=1] :
288
*/
264
*/
289
SEXP do_duplicated(SEXP call, SEXP op, SEXP args, SEXP env)
265
SEXP do_duplicated(SEXP call, SEXP op, SEXP args, SEXP env)
290
{
266
{
Line 927... Line 903...
927
    UNPROTECT(2); /*HashTable, matches*/
903
    UNPROTECT(2); /*HashTable, matches*/
928
    UNPROTECT(1); /*ans*/
904
    UNPROTECT(1); /*ans*/
929
    return ans;
905
    return ans;
930
}
906
}
931
 
907
 
-
 
908
/* returns 1-based duplicate no */
-
 
909
static int isDuplicated2(SEXP x, int indx, HashData *d)
-
 
910
{
-
 
911
    int i, *h;
-
 
912
 
-
 
913
    h = INTEGER(d->HashTable);
-
 
914
    i = d->hash(x, indx, d);
-
 
915
    while (h[i] != NIL) {
-
 
916
	if (d->equal(x, h[i], x, indx))
-
 
917
	    return h[i] + 1;
932
#include <R_ext/RS.h>
918
	i = (i + 1) % d->M;
-
 
919
    }
-
 
920
    h[i] = indx;
-
 
921
    return 0;
-
 
922
}
-
 
923
 
-
 
924
static SEXP duplicated2(SEXP x, HashData *d)
-
 
925
{
-
 
926
    SEXP ans;
-
 
927
    int *h, *v;
-
 
928
    int i, n;
-
 
929
 
-
 
930
    n = LENGTH(x);
-
 
931
    HashTableSetup(x, d);
-
 
932
    PROTECT(d->HashTable);
-
 
933
    ans = allocVector(INTSXP, n);
-
 
934
    UNPROTECT(1);
-
 
935
    h = INTEGER(d->HashTable);
-
 
936
    v = INTEGER(ans);
-
 
937
    for (i = 0; i < d->M; i++) h[i] = NIL;
-
 
938
    for (i = 0; i < n; i++) v[i] = isDuplicated2(x, i, d);
-
 
939
    return ans;
-
 
940
}
933
 
941
 
-
 
942
#include <R_ext/RS.h> /* for Calloc, free */
934
 
943
 
935
SEXP do_makeunique(SEXP call, SEXP op, SEXP args, SEXP env)
944
SEXP do_makeunique(SEXP call, SEXP op, SEXP args, SEXP env)
936
{
945
{
937
    SEXP names, sep, ans, dup, newx;
946
    SEXP names, sep, ans, dup, newx;
938
    int i, n, cnt, len, maxlen = 0;
947
    int i, n, cnt, len, maxlen = 0, *cnts, dp;
939
    HashData data;
948
    HashData data;
940
    char *csep, *buf;
949
    char *csep, *buf;
941
    
950
    
942
    checkArity(op, args);
951
    checkArity(op, args);
943
    names = CAR(args);
952
    names = CAR(args);
Line 955... Line 964...
955
    }
964
    }
956
    if(n > 1) {
965
    if(n > 1) {
957
	/* +2 for terminator and rounding error */
966
	/* +2 for terminator and rounding error */
958
	buf = Calloc(maxlen + strlen(csep) + log((double)n)/log(10.0) + 2, 
967
	buf = Calloc(maxlen + strlen(csep) + log((double)n)/log(10.0) + 2, 
959
		     char);
968
		     char);
-
 
969
	cnts = Calloc(n, int);
-
 
970
	for(i = 0; i < n; i++) cnts[i] = 1;
960
	data.nomatch = 0;
971
	data.nomatch = 0;
961
	PROTECT(newx = allocVector(STRSXP, 1));
972
	PROTECT(newx = allocVector(STRSXP, 1));
962
	PROTECT(dup = duplicated2(names, &data));
973
	PROTECT(dup = duplicated2(names, &data));
963
	PROTECT(data.HashTable);
974
	PROTECT(data.HashTable);
964
	for(i = 1; i < n; i++) { /* first cannot be a duplicate */
975
	for(i = 1; i < n; i++) { /* first cannot be a duplicate */
-
 
976
	    dp = INTEGER(dup)[i]; /* 1-based number of first occurrence */
965
	    if(!LOGICAL(dup)[i]) continue;
977
	    if(dp == 0) continue;
966
	    /* Try appending 1,2,3, ..., n-1 until it is not already in use */
978
	    /* Try appending 1,2,3, ..., n-1 until it is not already in use */
967
	    for(cnt = 1; cnt < n; cnt++) {
979
	    for(cnt = cnts[dp-1]; cnt < n; cnt++) {
968
		sprintf(buf, "%s%s%d", CHAR(STRING_ELT(names, i)), csep, cnt);
980
		sprintf(buf, "%s%s%d", CHAR(STRING_ELT(names, i)), csep, cnt);
969
		SET_STRING_ELT(newx, 0, mkChar(buf));
981
		SET_STRING_ELT(newx, 0, mkChar(buf));
970
		if(Lookup(ans, newx, 0, &data) == data.nomatch) break;
982
		if(Lookup(ans, newx, 0, &data) == data.nomatch) break;
971
	    }
983
	    }
972
	    SET_STRING_ELT(ans, i, STRING_ELT(newx, 0));
984
	    SET_STRING_ELT(ans, i, STRING_ELT(newx, 0));
973
	    /* insert it */ (void) isDuplicated(ans, i, &data);
985
	    /* insert it */ (void) isDuplicated(ans, i, &data);
-
 
986
	    cnts[dp-1] = cnt+1; /* cache the first unused cnt value */
974
	}
987
	}
-
 
988
	Free(cnts);
975
	Free(buf);
989
	Free(buf);
976
	UNPROTECT(3);
990
	UNPROTECT(3);
977
    }
991
    }
978
    UNPROTECT(1);
992
    UNPROTECT(1);
979
    return ans;
993
    return ans;