我想重复一个data.frame的行,每行N
倍。 结果应该是一个新的data.frame
(具有nrow(new.df) == nrow(old.df) * N
),保持列的数据类型。
例如,对于N = 2:
A B C
A B C 1 j i 100
1 j i 100 --> 2 j i 100
2 K P 101 3 K P 101
4 K P 101
因此,每一行重复2次和字符保持字符,因素仍然因素,NUMERICS保持数字,...
从前,我第一次尝试申请: apply(old.df, 2, function(co) rep(co, each = N))
但这一转变我的价值观,以人物和我得到:
A B C
[1,] "j" "i" "100"
[2,] "j" "i" "100"
[3,] "K" "P" "101"
[4,] "K" "P" "101"
Answer 1:
df <- data.frame(a=1:2, b=letters[1:2])
df[rep(seq_len(nrow(df)), each=2),]
Answer 2:
干净dplyr
解决方案,取自这里
library(dplyr)
df <- data_frame(x = 1:2, y = c("a", "b"))
df %>% slice(rep(1:n(), each = 2))
Answer 3:
如果你可以重复整个事情,或子集它首先然后重复这一点,那么这种类似的问题可能会有所帮助。 再来一次:
library(mefa)
rep(mtcars,10)
或者干脆
mefa:::rep.data.frame(mtcars)
Answer 4:
该rep.row功能似乎有时会列出列,从而导致记忆力不好hijinks。 我写这似乎运作良好的情况如下:
library(plyr)
rep.row <- function(r, n){
colwise(function(x) rep(x, n))(r)
}
Answer 5:
添加到什么@dardisco提及mefa::rep.data.frame()
它是非常灵活的。
您可以重复每行N次 :
rep(df, each=N)
或重复整个数据框N次 (认为:当您回收量化参数等)
rep(df, times=N)
两个大拇指的mefa
! 我从来没有听说过,到现在为止,我不得不写手工代码来做到这一点。
Answer 6:
作为参考,并添加到答案援引间位,可能值得采取的执行一脸mefa::rep.data.frame()
如果你不希望包括整个包:
> data <- data.frame(a=letters[1:3], b=letters[4:6])
> data
a b
1 a d
2 b e
3 c f
> as.data.frame(lapply(data, rep, 2))
a b
1 a d
2 b e
3 c f
4 a d
5 b e
6 c f
Answer 7:
我的解决方案类似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
}
比较的解决方案:
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
Answer 8:
存在着通过添加仅重复某些行N次每次,可能例如一个可爱的矢量溶液ntimes
列到数据帧:
A B C ntimes
1 j i 100 2
2 K P 101 4
3 Z Z 102 1
方法:
df <- data.frame(A=c("j","K","Z"), B=c("i","P","Z"), C=c(100,101,102), ntimes=c(2,4,1))
df <- as.data.frame(lapply(df, rep, df$ntimes))
结果:
A B C ntimes
1 Z Z 102 1
2 j i 100 2
3 j i 100 2
4 K P 101 4
5 K P 101 4
6 K P 101 4
7 K P 101 4
这是非常相似的乔希·奥布莱恩和马克·米勒的方法:
df[rep(seq_len(nrow(df)), df$ntimes),]
然而,这种方法显得相当慢一点:
df <- data.frame(A=c("j","K","Z"), B=c("i","P","Z"), C=c(100,101,102), ntimes=c(2000,3000,4000))
microbenchmark::microbenchmark(
df[rep(seq_len(nrow(df)), df$ntimes),],
as.data.frame(lapply(df, rep, df$ntimes)),
times = 10
)
结果:
Unit: microseconds
expr min lq mean median uq max neval
df[rep(seq_len(nrow(df)), df$ntimes), ] 3563.113 3586.873 3683.7790 3613.702 3657.063 4326.757 10
as.data.frame(lapply(df, rep, df$ntimes)) 625.552 654.638 676.4067 668.094 681.929 799.893 10
Answer 9:
尝试使用例如
N=2
rep(1:4, each = N)
作为指标
Answer 10:
另一种方式做,这会先得到行索引,追加DF额外的副本,然后通过索引顺序:
df$index = 1:nrow(df)
df = rbind(df,df)
df = df[order(df$index),][,-ncol(df)]
尽管其他的解决方案可以更短,这种方法可能在某些情况下更有利。
文章来源: Repeat rows of a data.frame