andrewH
andrewH

Reputation: 2321

Understanding the effect of c( ) on named vectors

Why is:

c(d = 1:3)

equal to a named vector, as:

d1 d2 d3 
1  2  3 

And where is this behavior documented?

The c help file does say:

## do *not* use
c(ll, d = 1:3) # which is == c(ll, as.list(c(d = 1:3))

but the as.list is superfluous (and the closing parenthesis missing). And I don't think that amounts to documentation of the behavior above.

Upvotes: 4

Views: 73

Answers (2)

amrrs
amrrs

Reputation: 6325

That's a nice observation which took me to the actual C Code (since c() is a Primitive function). Just sharing my observation from the code.

And in the actual C code do_c() function that does this c() for R and inside that function there's a section dedicated to assign attributes to the output.

/* Build and attach the names attribute for the returned object. */

    if (data.ans_nnames && data.ans_length > 0) {
    PROTECT(data.ans_names = allocVector(STRSXP, data.ans_length));
    data.ans_nnames = 0;
    while (args != R_NilValue) {
        struct NameData nameData;
        nameData.seqno = 0;
        nameData.count = 0;
        NewExtractNames(CAR(args), R_NilValue, TAG(args), recurse, &data, &nameData);
        args = CDR(args);
    }
    setAttrib(ans, R_NamesSymbol, data.ans_names);
    UNPROTECT(1);
    }

which tells us NewExtractNames() is the function that specifically create names and exploring that we can find the information that the sequence is created

/* NewExtractNames(v, base, tag, recurse):  For c() and  unlist().
 * On entry, "base" is the naming component we have acquired by
 * recursing down from above.
 *  If we have a list and we are recursing, we append a new tag component
 * to the base tag (either by using the list tags, or their offsets),
 * and then we do the recursion.
 *  If we have a vector, we just create the tags for each element. */

So, to your question it doesn't seem to have been documented anywhere that attribute names are generated with a sequence and assigned it to the result.

Hope it helps.

Upvotes: 2

Terru_theTerror
Terru_theTerror

Reputation: 5017

You can modify this behaviour changing use.names parameter:

c(d = 1:3)
d1 d2 d3 
 1  2  3 
c(d = 1:3,use.names=F)
[1] 1 2 3

More details here: https://www.rdocumentation.org/packages/base/versions/3.4.3/topics/c

Upvotes: 2

Related Questions