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?

1
  • Check out the new version(s) I added to my answer. I think that is the cleanest yet. Commented Feb 26, 2014 at 18:16

2 Answers 2

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>
Sign up to request clarification or add additional context in comments.

4 Comments

@January, I also added a base version.
Nice use of match in the base version, but note that this approach changes the integer column to character.
@BrodieG as Matthew pointed out, the first example has a deficiency (there was a reason I picked up a mixture of ints and characters...)
@January, see update, though I think at this point Matthew's is cleaner.
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)

1 Comment

Nice; how about df[1,][NA,] for the first line? Then we do not generate another data frame of the same size as df.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.