9

So I have this data frame

df <- data.frame( A=1:10, B=LETTERS[1:10], C=letters[1:10], stringsAsFactors= F )

I want to add a row to this data frame with A=11 and C="K", but I don't have the information on the column C. In fact, I have no idea a priori what other columns are there in the data frame, except for A and B. These missing columns should get an NA. The best I could come up is this:

tmp <- rep( NA, ncol( df ) ) # Batman!
df <- rbind( df, tmp )
df[ nrow( df ), "A" ] <- 11
df[ nrow( df ), "B" ] <- "K"

Is there a simpler way?

January
  • 16,320
  • 6
  • 52
  • 74

2 Answers2

14

Base version:

new.row <- list(A=11, B="K")
df[nrow(df) + 1, names(new.row)] <- new.row

plyr version:

library(plyr)
new.row <- data.frame(A=11, B="K", stringsAsFactors=F)
df <- rbind.fill(df, new.row)

Both produce:

    A B    C
1   1 A    a
2   2 B    b
3   3 C    c
4   4 D    d
5   5 E    e
6   6 F    f
7   7 G    g
8   8 H    h
9   9 I    i
10 10 J    j
11 11 K <NA>

You can also generalize the base version to more rows:

more.rows <- data.frame(A=15:20, B=letters[15:20], stringsAsFactors=F)
df[(nrow(df) + 1):(nrow(df) + nrow(more.rows)), names(more.rows)] <- more.rows

producing:

    A B    C
1   1 A    a
2   2 B    b
3   3 C    c
4   4 D    d
5   5 E    e
6   6 F    f
7   7 G    g
8   8 H    h
9   9 I    i
10 10 J    j
11 11 K <NA>
12 15 o <NA>
13 16 p <NA>
14 17 q <NA>
15 18 r <NA>
16 19 s <NA>
17 20 t <NA>
BrodieG
  • 51,669
  • 9
  • 93
  • 146
6

Here's an alternative base version that preserves the datatypes.

new.row <- head(df[NA,], 1)
new.row[c('A', 'B')] <- list(A=11, B='K')
rbind(df, new.row)
Matthew Plourde
  • 43,932
  • 7
  • 96
  • 113
  • 3
    Nice; how about `df[1,][NA,]` for the first line? Then we do not generate another data frame of the same size as df. – January Feb 26 '14 at 15:46