The above solution is very elegant and succinct. If you're interested in a function similar to the one described in the original posting to avoid the often slow call to rbind
, you could use this:
existingDF <- as.data.frame(matrix(seq(20),nrow=5,ncol=4))
rs <- c(2,4)
newrows <- matrix(seq(-8, -1),nrow=2,ncol=4)
insertRow <- function(existingDF, newrows, rs) {
rs <- sort(rs) + seq(0, length(rs) - 1)
old_rs <- seq(nrow(existingDF) + length(rs))[-rs]
existingDF[old_rs,] <- existingDF
existingDF[rs,] <- newrows
existingDF
}
insertRow(existingDF, newrows, rs)
This essentially also expands the old data frame by the number of new rows to be inserted but skips the indices of the new rows when reassigning the old data frame, and then inserts the new rows at the appropriate positions.
UPDATE: I forgot to take the shifting of the rows due to prior insertions into account, this is what the rs <- sort(rs) + seq(0, length(rs) - 1)
takes care of (now rows are inserted at the correct positions relative to the original data frame, i.e. always before the specified rows of the original data frame), without it, the new rows will be inserted exactly at the positions in the data frame that are specified.
UPDATE2: and this is a modification to use the function directly with the original data set put forth by the OP
x <- matrix(as.character(seq(100)),20,5)
tmp <- rbind(c(6,letters[1:5]),c(15,LETTERS[1:5]))
insertRow <- function(existingDF, newrows) {
new_idx <- as.integer(newrows[,1]) # get indices of the new rows
new_idx <- sort(new_idx) + seq(0, length(new_idx) - 1) # adjust for rows shifting due to other insertions
old_idx <- seq(nrow(existingDF) + length(new_idx))[-new_idx] # ge indices for the old rows
existingDF[old_idx,] <- existingDF # assign old rows
existingDF[new_idx,] <- newrows[,-1] # assign new rows
existingDF
}
insertRow(data.frame(x, stringsAsFactors = F), tmp)