【发布时间】:2015-06-26 22:20:32
【问题描述】:
我正在尝试使用下面的代码在我的数据框中复制行。 但是,我发现它很慢。
duprow = df[1,]
for(i in 1:2000)
{
print(i)
df = rbind(df,duprow)
}
有没有更快的方法?
【问题讨论】:
我正在尝试使用下面的代码在我的数据框中复制行。 但是,我发现它很慢。
duprow = df[1,]
for(i in 1:2000)
{
print(i)
df = rbind(df,duprow)
}
有没有更快的方法?
【问题讨论】:
您可以使用rep,例如对于 5 个重复项或第 1 行:
df <- data.frame(x = 1, y = 1)
rbind(df, df[rep(1, 5), ])
# x y
# 1 1 1
# 11 1 1
# 1.1 1 1
# 1.2 1 1
# 1.3 1 1
# 1.4 1 1
【讨论】:
这是我的破解:
> # create an example data frame
> colornames=c("violet","indigo","blue","green","yellow","orange","red")
> wavelength=c(400,425,470,550,600,630,665)
> df <- data.frame(colornames, wavelength)
>
> # How many replicates you want of each row
> duptimes <- c(0,1,2,1,1,4,1)
>
> # Create an index of the rows you want with duplications
> idx <- rep(1:nrow(df), duptimes)
>
> # Use that index to genderate your new data frame
> dupdf <- df[idx,]
>
> # display results
> df
colornames wavelength
1 violet 400
2 indigo 425
3 blue 470
4 green 550
5 yellow 600
6 orange 630
7 red 665
> dupdf
colornames wavelength
2 indigo 425
3 blue 470
3.1 blue 470
4 green 550
5 yellow 600
6 orange 630
6.1 orange 630
6.2 orange 630
6.3 orange 630
7 red 665
我不知道这是否更快,但它不需要加载额外的包并且还删除不需要的行。
缺点是您需要对数据框中的每一行做出决定,但这应该不会太难编码。
【讨论】:
reptimes <- 12; idx <- rep(1:nrow(df), reptimes); rep_df <- df[idx, ]
我昨天遇到了类似的问题,还有一个名为“splitstackshape”的包。那么就很简单了,如下代码:
library(splitstackshape)
df <- data.frame(x = 1, y = 1)
df2 <- expandRows(df, count=2000, count.is.col=FALSE)
您可能还想通过以下方式“修复”行名
rownames(df2) <- 1:2000
【讨论】:
rownames(df2) <- NULL来达到同样的效果。或者,如果输入是data.table,则不会以行名开头。例如:expandRows(as.data.table(df), count = 2000, count.is.col = FALSE)
Luke 使用 rep() 的回答暂时可以完成您的工作,但从长远来看,以下这些回答可能会对您有所帮助。
请在speeding up rbind 上查看这个答案,了解为什么它很慢并且不使用循环。它还具有预先分配数据帧的代码。另请参阅 jorans Second circle of hell comment。
建议 rbind.fill 来自@coanil
我想补充两点:1)一般情况下,如果你不想使用data.table,你可以使用Hadley的plyr包中的rbind.fill函数,速度也很快。永远不要像上面那样在“for”循环中使用 rbind,分别附加每一行。每次追加一行时,它都会强制 R 复制数据框对象,这很慢。
https://stackoverflow.com/a/19699342/4606130
data.table路线,那么使用更快的rbindlist。 (@David 在第一个答案链接中建议了这一点。)【讨论】:
我有一个类似的问题,我想使用dplyr 以整洁的方式解决它。我最终使用dplyr::filter() 和dplyr::row_number() 根据行号从我的数据框中过滤了指定的行。并使用dplyr::bind_rows() 将它们绑定到原始数据帧,所有这些都在一个管道中。在您的示例中,它将是这样的:
df %>%
filter(row_number() <= 2000) %>%
bind_rows(df)
如果您想复制特定的行,快速简单!当然,您可以使用特定的行号进行复制,使用filter(row_number() %in% c(...))。
【讨论】: