TARehman
TARehman

Reputation: 6749

Why does R's attributes() function fail when using explicit arguments?

I am working with RODBC and parallel to make multiple queries against a data system for some internal reporting. To facilitate making new connections, I am going to extract the connection string from the RODBC object. To do this, I planned to use attributes(). However, I've encountered a behavior that I do not understand. A minimal working example is below:

> example.data <- data.frame(letters = sample(x = LETTERS,size = 20,replace = T),
+                            numbers = sample(x = 0:9,size = 20,replace = T))
> 
> attributes(obj = example.data)
Error in attributes(obj = example.data) : 
  supplied argument name 'obj' does not match 'x'
> attributes(example.data)
$names
[1] "letters" "numbers"

$row.names
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

$class
[1] "data.frame"

It should be noted that the obj = behavior is the one tab-suggested by RStudio. However, it causes an error. I tried to review the source code for attributes, but it is a primitive, so I would have to go digging into the C source - with which I am not nearly as familiar.

Why does attributes() fail when an explicit argument (obj =) is used, but runs fine when it is not used? (And should the behavior of RStudio with regard to suggesting obj = be changed?)

Upvotes: 4

Views: 563

Answers (1)

MrFlick
MrFlick

Reputation: 206411

This seems like a bug in the documentation for attributes. The parameter probably should be named x. You can call it that way

attributes(x = example.data)

The problem is that attributes() is a primitive function and primitive functions behave differently than regular functions in R. They don't have formal parameters (formals(attributes) returns NULL). For these types of functions, R typically isn't going to parse out parameters by name and will assume they are in a certain positional order for efficiency reasons. That's why it's better not to name them because you cannot change the order of these parameters. There should be no need to name the parameter here.

There are other functions out there that have mismatches between the parameter name in the documentation and the value checked by the code. For example

isS4(pi)
# [1] FALSE
# documented parameter name is "object"
isS4(object=pi)
# Error in isS4(object = pi) : 
#   supplied argument name 'object' does not match 'x'
isS4(x=pi)
# [1] FALSE

But there are also other primitives out there that use names other than x: e.g. seq_along (uses "along.with=") and quote (uses "expr=").

Upvotes: 5

Related Questions