重复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可能更短,但是这种方法在某些情况下可能更有利。