Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重复data.frame的行_R_Dataframe_Rows_Repeat - Fatal编程技术网

重复data.frame的行

重复data.frame的行,r,dataframe,rows,repeat,R,Dataframe,Rows,Repeat,我想重复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 1

我想重复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次,字符保留字符,因子保留因子,数字保留数字

我的第一次尝试使用apply:
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"
df尝试使用例如

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

作为索引

如果您可以重复整个内容,或者先将其子集,然后再重复,那么可能会有所帮助。再次:

library(mefa)
rep(mtcars,10) 
或者干脆

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

rep.row函数有时似乎会为列创建列表,这会导致内存错误。我写了以下内容,似乎效果不错:

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

rep.row除了@dardisco提到的mefa::rep.data.frame()
之外,它非常灵活

您可以将每行重复N次

rep(df, each=N)
或者将整个数据帧重复N次(想想:就像回收向量化参数一样)


向mefa竖起两个大拇指!直到现在我才听说过它,为此我必须编写手动代码。

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

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

尽管其他解决方案可能较短,但在某些情况下,此方法可能更为有利。

作为参考并添加到引用mefa的答案中,如果您不想包含整个程序包,则可能需要查看
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
>数据
a b
1 a d
2 b e
3立方英尺
>as.data.frame(lappy(数据,rep,2))
a b
1 a d
2 b e
3立方英尺
公元4年
5 b e
6立方英尺

我的解决方案类似于
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
}

清洁的
dplyr
溶液,取自

库(dplyr)
df%切片(代表(1:n(),每个=2))

有一个可爱的矢量化解决方案,它只会将某些行重复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))
这与Josh O'Brien和Mark Miller的方法非常相似:

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
)

你可以使用
n次啊哈!另一个出色的R函数隐藏在一个obcure专家包的深处,它的名字完全不相关。我喜欢这种语言!这是imo的首选解决方案,因为它可以在管道中干净地工作。
  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