Skip to content

cbind error with check.names

8 messages · Ista Zahn, William Dunlap, Fg Nu

#
Here is an example where?cbind?fails with an error when?check.names=TRUE?is set.

data(airquality)
airQualityBind =cbind(airquality,airquality,check.names =TRUE)


?I understand that?cbind?is a call to?data.frame?and the following works:
airQualityBind =data.frame(airquality,airquality,check.names =TRUE)
but I would like to understand why?cbind?throws an error.

I asked this question on SO here:
http://stackoverflow.com/questions/17810470/cbind-error-with-check-names
and user?Hong Ooi?confirmed my suspicion that cbind was passing check.names = FALSE regardless of my setting that option, even though the help file indicates that this should be possible,?

"For the "data.frame" method of cbind these can be further arguments to data.frame such as stringsAsFactors."

Is there some design principle that I am missing here?

Thanks.
#
On Tue, Jul 23, 2013 at 9:18 AM, Fg Nu <fgnu32 at yahoo.com> wrote:
Well, the function does work as documented. See the help file section
on "Data frame methods", which says "The 'cbind' data frame method is
just a wrapper for 'data.frame(..., check.names = FALSE)'".

Best,
Ista
#
----- Original Message -----
From: Ista Zahn <istazahn at gmail.com>
To: Fg Nu <fgnu32 at yahoo.com>
Cc: "r-devel at r-project.org" <r-devel at r-project.org>
Sent: Tuesday, July 23, 2013 9:50 PM
Subject: Re: [Rd] cbind error with check.names
On Tue, Jul 23, 2013 at 9:18 AM, Fg Nu <fgnu32 at yahoo.com> wrote:
Well, the function does work as documented. See the help file section
on "Data frame methods", which says "The 'cbind' data frame method is
just a wrapper for 'data.frame(..., check.names = FALSE)'".

Best,
Ista



Is there then a reason that overriding the check.names default is forbidden from cbind? I can't tell why this would be the case.

Thanks
#
On Tue, Jul 23, 2013 at 12:54 PM, Fg Nu <fgnu32 at yahoo.com> wrote:
For the same reason you can't have

data.frame(x=1:10, x=11:20, check.names=TRUE, check.names=FALSE)

or

mean(x=1:10, x=11:20)

i.e, you can't generally pass the same argument more than once. There
are exceptions to this, e.g.,

sum(c(NA, 1:10), na.rm=TRUE, na.rm=FALSE)

but in general each argument can only be matched once. Since
cbind.data.frame calls data.frame with check.names=FALSE, you can't
supply it again.

Best,
Ista
#
----- Original Message -----
From: Ista Zahn <istazahn at gmail.com>
To: Fg Nu <fgnu32 at yahoo.com>
Cc: "r-devel at r-project.org" <r-devel at r-project.org>
Sent: Tuesday, July 23, 2013 11:05 PM
Subject: Re: [Rd] cbind error with check.names
On Tue, Jul 23, 2013 at 12:54 PM, Fg Nu <fgnu32 at yahoo.com> wrote:
For the same reason you can't have

data.frame(x=1:10, x=11:20, check.names=TRUE, check.names=FALSE)

or

mean(x=1:10, x=11:20)

i.e, you can't generally pass the same argument more than once. There
are exceptions to this, e.g.,

sum(c(NA, 1:10), na.rm=TRUE, na.rm=FALSE)

but in general each argument can only be matched once. Since
cbind.data.frame calls data.frame with check.names=FALSE, you can't
supply it again.

Best,
Ista
Yikes, no. As I mentioned to the SO poster, I get that bit.

I meant what is the design principle behind check.names being hardcoded to FALSE. I see no conflict with the purpose of cbind from the ability to specify check.names at the level of cbind.
#
For the same reason you can't have

data.frame(x=1:10, x=11:20, check.names=TRUE, check.names=FALSE)

or

mean(x=1:10, x=11:20)

i.e, you can't generally pass the same argument more than once. There
are exceptions to this, e.g.,

sum(c(NA, 1:10), na.rm=TRUE, na.rm=FALSE)

but in general each argument can only be matched once. Since
cbind.data.frame calls data.frame with check.names=FALSE, you can't
supply it again.

Best,
Ista
Yikes, no. As I mentioned to the SO poster, I get that bit.

I meant what is the design principle behind check.names being hardcoded to FALSE. I see no conflict with the purpose of cbind from the ability to specify check.names at the level of cbind.
#
One rationale is that data.frame(check.names=TRUE,...) does two things: it makes
sure there are no duplicate names and it makes sure that all the names are syntactic
names.  If you have created a data.frame with non-syntactic names you would be annoyed
if a call to cbind mangled its names, hence cbind.data.frame sets check.names=FALSE
to avoid this.
  > d1 <- data.frame(`Mass (g)`=102, `Conc (% by vol.)`=0.23, check.names=FALSE)
  > d2 <- data.frame(`Accel (m/s/s)`=9.81, `Conc (% by vol.)`=0.23, check.names=FALSE)
  > names(d1)
  [1] "Mass (g)"         "Conc (% by vol.)"
  > names(d2)
  [1] "Accel (m/s/s)"    "Conc (% by vol.)"
  > names(data.frame(d1, d2, check.names=TRUE))
  [1] "Mass..g."           "Conc....by.vol.."   "Accel..m.s.s."      "Conc....by.vol...1"
  > names(data.frame(d1, d2, check.names=FALSE))
  [1] "Mass (g)"         "Conc (% by vol.)" "Accel (m/s/s)"    "Conc (% by vol.)"
  > names(cbind(d1, d2))
  [1] "Mass (g)"         "Conc (% by vol.)" "Accel (m/s/s)"    "Conc (% by vol.)"

Perhaps data.frame() should throw an error if there are duplicate names,
or perhaps it should have a separate argument to say what to do about duplicate names,
but changing that sort of thing now would break a fair bit of code.  Perhaps
cbind.data.frame should not call data.frame, but copy the work that data.frame
does or perhaps it should check for duplicate names on the output of data.frame().
Is it worth the time to do that?

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
#
Bill, thanks for your reply. I understand that this is one of things that just are. For me, the ability to check for duplicate names in dataframes is important, and it is surprising that I never realised before that cbind has this limitation.