在R中的数据框中出现重复行

19

我正在尝试使用以下代码复制数据框中的行。 但是,我发现速度很慢。

duprow = df[1,]
for(i in 1:2000)
{
    print(i)
    df = rbind(df,duprow)
}

有更快的方法吗?

5个回答

20
你可以使用rep,例如对于数据框中第1行的5个副本。
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

这是一个聪明的技巧,只需将要替换的行号作为索引复制到数据框中。 - DashdotdotDashdotdot

15
这是我的尝试:
> # 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

我不知道这个方法是否更快,但它不需要加载额外的数据包并且还可以去除不需要的行。

缺点是你需要对数据框中的每一行进行决策,但这应该不难编码。


3
使用起始行数为1百万的数据框,这个方法对我很有效且速度快。如果您想让每一行重复相同的次数,可以使用reptimes <- 12; idx <- rep(1:nrow(df), reptimes); rep_df <- df[idx, ] - mikey
1
这个技巧非常巧妙。它也适用于向量,并且您可以多次应用它来嵌套数据。 - piegames

5

我遇到了一个类似的问题,希望能够用 dplyr 来整洁地解决。最终我使用 dplyr::filter()dplyr::row_number() 通过行号从数据框中过滤出需要的行,并将它们与原始数据框使用 dplyr::bind_rows() 绑定在一起,全部在一条管道中完成。在你的例子中,可以像这样实现:

df %>% 
  filter(row_number() <= 2000) %>% 
  bind_rows(df)

如果您想要快速简单地复制特定行,则可以使用 filter(row_number() %in% c(...)) 并指定特定的行号来进行复制。


3

我昨天也遇到了类似的问题,还有一个叫做“splitstackshape”的包。然后只需要按照以下代码即可:

library(splitstackshape)
df <- data.frame(x = 1, y = 1)
df2 <- expandRows(df, count=2000, count.is.col=FALSE)

您可能还想通过以下方式“修复”行名称:
```R rownames(df) <- NULL ```
rownames(df2) <- 1:2000

我通常只需使用 rownames(df2) <- NULL 来实现相同的效果。或者,如果输入是一个 data.table,一开始就不会有行名。例如:expandRows(as.data.table(df), count = 2000, count.is.col = FALSE) - A5C1D2H2I1M1N2O1R2T1

3

目前Luke使用rep()的答案可以解决您的问题,但以下答案可能有助于您更长远的发展。

  1. 请查看加速rbind中的此答案,了解为什么它很慢以及不要使用循环。它还有代码来预分配您的数据框。还请参见jorans第二层地狱评论

  2. 建议rbind.fill来自@coanil

    我想添加两件事:1)通常,如果您不想使用data.table,则可以使用Hadley的plyr包中的rbind.fill函数,这也非常快。永远不要像上面那样在“for”循环中使用rbind,逐个附加每一行。它会强制R在附加一行时每次复制数据框对象,并且速度很慢。

https://dev59.com/Z2Ij5IYBdhLWcg3w_5vl#19699342

  1. 如果您选择使用data.table,则使用rbindlist更快。 (@David在第一个答案链接中建议使用此方法。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接