r - 在特定的行索引处向数据框添加新行,而不是附加?

标签 r dataframe insert

以下代码结合了向量和数据框:

newrow = c(1:4)
existingDF = rbind(existingDF,newrow)

但是这段代码总是在数据帧的末尾插入新行。

如何在数据框中的指定点插入行?例如,假设数据框有 20 行,我如何在第 10 行和第 11 行之间插入新行?

最佳答案

这是一个避免(通常很慢)rbind 调用的解决方案:

existingDF <- as.data.frame(matrix(seq(20),nrow=5,ncol=4))
r <- 3
newrow <- seq(4)
insertRow <- function(existingDF, newrow, r) {
  existingDF[seq(r+1,nrow(existingDF)+1),] <- existingDF[seq(r,nrow(existingDF)),]
  existingDF[r,] <- newrow
  existingDF
}

> insertRow(existingDF, newrow, r)
  V1 V2 V3 V4
1  1  6 11 16
2  2  7 12 17
3  1  2  3  4
4  3  8 13 18
5  4  9 14 19
6  5 10 15 20

如果速度不如清晰重要,那么@Simon 的解决方案效果很好:

existingDF <- rbind(existingDF[1:r,],newrow,existingDF[-(1:r),])
> existingDF
   V1 V2 V3 V4
1   1  6 11 16
2   2  7 12 17
3   3  8 13 18
4   1  2  3  4
41  4  9 14 19
5   5 10 15 20

(注意我们索引 r 的方式不同)。

最后,基准测试:

library(microbenchmark)
microbenchmark(
  rbind(existingDF[1:r,],newrow,existingDF[-(1:r),]),
  insertRow(existingDF,newrow,r)
)

Unit: microseconds
                                                    expr     min       lq   median       uq       max
1                       insertRow(existingDF, newrow, r) 660.131 678.3675 695.5515 725.2775   928.299
2 rbind(existingDF[1:r, ], newrow, existingDF[-(1:r), ]) 801.161 831.7730 854.6320 881.6560 10641.417

基准

正如@MatthewDowle 总是向我指出的那样,随着问题规模的增加,需要检查基准以进行缩放。那么我们开始吧:

benchmarkInsertionSolutions <- function(nrow=5,ncol=4) {
  existingDF <- as.data.frame(matrix(seq(nrow*ncol),nrow=nrow,ncol=ncol))
  r <- 3 # Row to insert into
  newrow <- seq(ncol)
  m <- microbenchmark(
   rbind(existingDF[1:r,],newrow,existingDF[-(1:r),]),
   insertRow(existingDF,newrow,r),
   insertRow2(existingDF,newrow,r)
  )
  # Now return the median times
  mediansBy <- by(m$time,m$expr, FUN=median)
  res <- as.numeric(mediansBy)
  names(res) <- names(mediansBy)
  res
}
nrows <- 5*10^(0:5)
benchmarks <- sapply(nrows,benchmarkInsertionSolutions)
colnames(benchmarks) <- as.character(nrows)
ggplot( melt(benchmarks), aes(x=Var2,y=value,colour=Var1) ) + geom_line() + scale_x_log10() + scale_y_log10()

@Roland 的解决方案扩展性很好,即使调用了 rbind:

                                                              5       50     500    5000    50000     5e+05
insertRow2(existingDF, newrow, r)                      549861.5 579579.0  789452 2512926 46994560 414790214
insertRow(existingDF, newrow, r)                       895401.0 905318.5 1168201 2603926 39765358 392904851
rbind(existingDF[1:r, ], newrow, existingDF[-(1:r), ]) 787218.0 814979.0 1263886 5591880 63351247 829650894

以线性比例绘制:

linear

和对数对数刻度:

log-log

关于r - 在特定的行索引处向数据框添加新行,而不是附加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43345105/

相关文章:

r - 将 nls 应用于列表中的元素

r - 在不对列进行排序的情况下从宽转换为长

database - 数据框到数据库表

c# - 为什么 BLToolkit 在生成的查询中插入\0 而不是 '@' 符号?

PHP/MySQL 插入

r - n 列减法数

r - 如何根据我指定的变量在 ggplot 中排序点

arrays - 用 NULL 子集数组不会删除维度?

R,在 data.frame 中找到连续时间步长的平均长度

Java Oracle 插入查询