Scuba Steve
Scuba Steve

Reputation: 349

R can't find a function

I'm trying to rename a column without creating an object (dataframe).

When I run:

names(data.frame(cbind(LETTERS[1:3],1:3)))[1]<-"A"

I get:

Error in names(data.frame(cbind(LETTERS[1:3], 1:3)))[1] <- "A" : could not find function "data.frame<-"

If I run:

X<-data.frame(cbind(LETTERS[1:3],1:3))
colnames(X)[1]<-"letters"
X

I'll see the column name changed because I made a data frame and then changed it. I'm pretty sure these two code snippets are the same except for the object creation. I don't know if R is just inflexible on this function and I have to create objects sometimes and not others. But the error "...could not find function" seemed a bit odd to me. Can someone explain this error?

Upvotes: 4

Views: 3514

Answers (2)

BrodieG
BrodieG

Reputation: 52647

What do you expect the return value of your first command to be? Consider:

> (colnames(X)[1]<-"letters")
[1] "letters"

So even there in order to see the data frame output you have to run another command. Maybe setNames gets you part of the way to where you want to be:

> setNames(data.frame(cbind(LETTERS[1:3],1:3)), c("letters"))
  letters NA
1       A  1
2       B  2
3       C  3

Or better yet:

> data.frame(letters=LETTERS[1:3], 1:3)
  letters V2
1       A  1
2       B  2
3       C  3

Upvotes: 5

Aaron - mostly inactive
Aaron - mostly inactive

Reputation: 37764

As others have said, you need to name the data frame first. (Though there is a way to avoid that; stay tuned.) But you knew that already, and wanted to know why. Here it is.

Functions like this are replacement functions. They're a kind of "syntactic sugar" that makes certain kind of operations simpler. See this answer for details: https://stackoverflow.com/a/11563358/210673.

Here's an example of a replacement function and what it's really equal to.

names(d) <- c("A","B")
d <- `names<-`(d, c("A","B"))

Therefore your call is really (taking the result from cbind out for simplicity)

tmp <- cbind(LETTERS[1:3],1:3)
data.frame(tmp) <- `names<-`(data.frame(tmp), c("A","B"))

which in turn is trying to call

tmp <- `data.frame<-`(tmp, `names<-`(data.frame(tmp), c("A","B")))

and it fails because there is no data.frame<- function.

You can accomplish what you want by not using the syntactic sugar version of names<- but instead using it directly, as this won't try to do the assignment.

`names<-`(data.frame(tmp), c("A","B"))

Upvotes: 15

Related Questions