重复data.frame的行

我想重复一个data.frame的行,每个N次。 结果应该是一个新的data.frame (使用nrow(new.df) == nrow(old.df) * N )保持列的数据types。

N = 2的示例:

  ABC ABC 1 ji 100 1 ji 100 --> 2 ji 100 2 KP 101 3 KP 101 4 KP 101 

所以,每行重复2次,字符保持字符,因素保持因素,数字保持数字,… … –

我第一次尝试使用apply apply(old.df, 2, function(co) rep(co, each = N)) ,但是这个将我的值转换为字符,我得到:

  ABC [1,] "j" "i" "100" [2,] "j" "i" "100" [3,] "K" "P" "101" [4,] "K" "P" "101" 
 df <- data.frame(a=1:2, b=letters[1:2]) df[rep(seq_len(nrow(df)), each=2),] 

rep.row函数似乎有时会为列创build列表,这会导致内存不足hijinks。 我写了以下似乎很好的工作:

 library(plyr) rep.row <- function(r, n){ colwise(function(x) rep(x, n))(r) } 

如果你可以重复整个事情,或者先重复它,那么这个类似的问题可能会有所帮助。 再来一次:

 library(mefa) rep(mtcars,10) 

或干脆

 mefa:::rep.data.frame(mtcars) 

添加到@dardisco提到的有关mefa::rep.data.frame() ,它非常灵活。

您可以重复每一行N次

 rep(df, each=N) 

重复整个dataframeN次 (想想:就像当你回收一个向量化的参数)

 rep(df, times=N) 

两个mefa ! 到目前为止,我从来没有听说过,我不得不写手动代码来做到这一点。

为了引用和增加引用mefa的答案,如果你不想包含整个包,可以参考一下mefa::rep.data.frame()的实现。

 > data <- data.frame(a=letters[1:3], b=letters[4:6]) > data ab 1 ad 2 be 3 cf > as.data.frame(lapply(data, rep, 2)) ab 1 ad 2 be 3 cf 4 ad 5 be 6 cf 

尝试使用例如

 N=2 rep(1:4, each = N) 

作为索引

我的解决scheme类似mefa:::rep.data.frame ,但速度更快一些,并关心行名:

 rep.data.frame <- function(x, times) { rnames <- attr(x, "row.names") x <- lapply(x, rep.int, times = times) class(x) <- "data.frame" if (!is.numeric(rnames)) attr(x, "row.names") <- make.unique(rep.int(rnames, times)) else attr(x, "row.names") <- .set_row_names(length(rnames) * times) x } 

比较解决scheme

 library(Lahman) library(microbenchmark) microbenchmark( mefa:::rep.data.frame(Batting, 10), rep.data.frame(Batting, 10), Batting[rep.int(seq_len(nrow(Batting)), 10), ], times = 10 ) #> Unit: milliseconds #> expr min lq mean median uq max neval cld #> mefa:::rep.data.frame(Batting, 10) 127.77786 135.3480 198.0240 148.1749 278.1066 356.3210 10 a #> rep.data.frame(Batting, 10) 79.70335 82.8165 134.0974 87.2587 191.1713 307.4567 10 a #> Batting[rep.int(seq_len(nrow(Batting)), 10), ] 895.73750 922.7059 981.8891 956.3463 1018.2411 1127.3927 10 b 

另一种方法是首先获取行索引,附加额外的df副本,然后按索引sorting:

 df$index = 1:nrow(df) df = rbind(df,df) df = df[order(df$index),][,-ncol(df)] 

尽pipe其他解决scheme可能更短,但是这种方法在某些情况下可能更有利。