47

Possible Duplicate:
R: losing column names when adding rows to an empty data frame

I created an empty dataframe with column names only as follows

> compData <- data.frame(A= numeric(0), B= numeric(0))
> compData
[1] A B
<0 rows> (or 0-length row.names)
> compData <- rbind(compData,c(5,443))
> compData
  X5 X443
1  5  443

in the above after adding one row the column names are changed. How can I add new row data to data-frame?

Community
  • 1
  • 1
Surjya Narayana Padhi
  • 7,741
  • 25
  • 81
  • 130

6 Answers6

35

Adding to a zero-row data.frame will act differently to adding to an data.frame that already contains rows

From ?rbind

The rbind data frame method first drops all zero-column and zero-row arguments. (If that leaves none, it returns the first argument with columns otherwise a zero-column zero-row data frame.) It then takes the classes of the columns from the first data frame, and matches columns by name (rather than by position). Factors have their levels expanded as necessary (in the order of the levels of the levelsets of the factors encountered) and the result is an ordered factor if and only if all the components were ordered factors. (The last point differs from S-PLUS.) Old-style categories (integer vectors with levels) are promoted to factors.

You have a number of options --

the most straightforward

 compData[1, ] <- c(5, 443)

more complicated

Or you could coerce c(5,433) to a list or data.frame

rbind(compData,setNames(as.list(c(5,443)), names(compData)))

or

rbind(compData,do.call(data.frame,setNames(as.list(c(5,443)), names(compData))))

But in this case you might as well do

do.call(data.frame,setNames(as.list(c(5,443)), names(compData)))

data.table option

You could use the data.table function rbindlist which does less checking and thus preserves the names of the first data.frame

library(data.table)
rbindlist(list(compData, as.list(c(5,443))
mnel
  • 113,303
  • 27
  • 265
  • 254
25

I just got a simpler way to do it... as follows

compData <- data.frame(A= numeric(0), B= numeric(0))
compData
compData[nrow(compData)+1, ] <- c(5, 443)
compData
Surjya Narayana Padhi
  • 7,741
  • 25
  • 81
  • 130
7
Colnames <- names(compData)
compData <- rbind(compData, c(5, 443))
names(compData) <- Colnames
Maiasaura
  • 32,226
  • 27
  • 104
  • 108
5

You can use the function structure with the .Names argument:

compData <- structure(rbind(compData,c(5,443)), .Names = names(compData))

#  A   B
#1 5 443
Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168
4

You can assign to the dataframe by index:

compData <- data.frame(A= numeric(0), B= numeric(0))
compData
compData[1, ] <- c(5, 443)
compData

Which gives:

> compData <- data.frame(A= numeric(0), B= numeric(0))
> compData
[1] A B
<0 rows> (or 0-length row.names)
> compData[1, ] <- c(5, 443)
> compData
  A   B
1 5 443
Marius
  • 58,213
  • 16
  • 107
  • 105
  • 1
    Is it possible to append the row to data-frame without knowing the index? Because its difficult sometimes to know which indexes we have to update – Surjya Narayana Padhi Sep 27 '12 at 05:27
  • @SurjyaNarayanaPadhi - your question is **specific** in that you are adding to a empty data.frame, therefore you always know that the row will start at 1 – mnel Sep 27 '12 at 06:25
2

If you have data of the same type*, you can do the following:

  1. Convert actual data frame to a matrix.
    as.matrix(compData)
  2. Add the new row to the end.
    rbind(as.matrix(compData), c(5,443))
  3. Convert the matrix back to a data frame.
    as.data.frame(rbind(as.matrix(compData), c(5,443)))

In short:
compData <- as.data.frame(rbind(as.matrix(compData), c(5,443)))

*If you have data of the same type, you might want to keep them in a matrix.

srctaha
  • 1,394
  • 1
  • 14
  • 16