0

I have the following to create a data frame. My problem is that the data frame row names display as [1,],[2,],[3,],[4,], etc instead of just 1,2,3,4,etc (see below for outputs). Why and how can I fix this to just have my row names show as usual (incremented number).

Code:

df <- data.frame(id=c("id"),nobs=c("nobs"))
df <- cbind(id,nobs)
df

id and nobs are two vectors with 5 numeric values each...

Current output:
     id nobs
[1,]  2 3653
[2,]  4 3653
[3,]  8 1462
[4,] 10 1097
[5,] 12  732

Desired output:
   id nobs
1  2 3653
2  4 3653
3  8 1462
4 10 1097
5 12  732
M--
  • 25,431
  • 8
  • 61
  • 93
mo_maat
  • 2,110
  • 12
  • 44
  • 72

2 Answers2

4

Your second command completely overwrites the first. What you want is

df <- data.frame(id=id, nobs=nobs)

Since your inputs to cbind are vectors (I presume), then by default it returns a matrix.

Additionally you could force it as a data frame via

df <- data.frame(cbind(id, nobs))

but that is overkill.

Paul Raff
  • 306
  • 2
  • 9
  • 1
    +1 For recommending the use of `data.frame()` directly. Too many people get sucked into the vortex of using `cbind` to build data frames when it isn't necessary, and usually just causes problems. – joran Jan 18 '13 at 17:12
  • Thank you Paul. That worked and I understand better now. Also, sorry if I did not make your answer the selected one. I just went with the first one I saw from Arun. – mo_maat Jan 19 '13 at 11:05
0

Note: I don't suggest that you should use either of these methods. If you want a data.frame, you can create it directly as Paul has showed (or you yourself have done). This is just to illustrate why this happens. Although sometimes when using sapply for example, the output would be a matrix and you might want to bind 2 such matrices and have them as a data.frame.

From the help page for cbind (?cbind):

The functions cbind and rbind are S3 generic, with methods for data frames. The data frame method will be used if at least one argument is a data frame and the rest are vectors or matrices.

Data frame methods

The cbind data frame method is just a wrapper for data.frame(..., check.names = FALSE). This means that it will split matrix columns in data frame arguments, and convert character columns to factors unless stringsAsFactors = FALSE is specified.

So, if you pass two vectors, the wrapper for data.frame won't be called. Hence, you obtain a matrix.

What can you do?
1) you could create and pass at least one data.frame argument to cbind
2) wrap the cbind argument with a as.data.frame(.).

x <- 1:5
y <- 6:10
> cbind(data.frame(x), y)
  x  y
1 1  6
2 2  7
3 3  8
4 4  9
5 5 10

> as.data.frame(cbind(x,y))
  x  y
1 1  6
2 2  7
3 3  8
4 4  9
5 5 10
Arun
  • 116,683
  • 26
  • 284
  • 387
  • Thank you Arun! This was helpful. I'm new to R and now I see how the built in help actually is useful. I suspected it but just wasn't sure. Also, sorry if I did not – mo_maat Jan 19 '13 at 11:03