【问题标题】:duplicate rows in a data frame in RR中数据框中的重复行
【发布时间】:2015-06-26 22:20:32
【问题描述】:

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

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

有没有更快的方法?

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    您可以使用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
    

    【讨论】:

      【解决方案2】:

      这是我的破解:

      > # 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
      

      我不知道这是否更快,但它不需要加载额外的包并且还删除不需要的行。

      缺点是您需要对数据框中的每一行做出决定,但这应该不会太难编码。

      【讨论】:

      • 这对我来说效果很好,并且使用以 100 万行开头的数据框很快。如果你想为每一行重复相同的次数,你可以使用reptimes &lt;- 12; idx &lt;- rep(1:nrow(df), reptimes); rep_df &lt;- df[idx, ]
      • 这个技巧很巧妙。它也适用于向量,您可以多次将其应用于嵌套数据。
      【解决方案3】:

      我昨天遇到了类似的问题,还有一个名为“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) &lt;- NULL来达到同样的效果。或者,如果输入是data.table,则不会以行名开头。例如:expandRows(as.data.table(df), count = 2000, count.is.col = FALSE)
      【解决方案4】:

      Luke 使用 rep() 的回答暂时可以完成您的工作,但从长远来看,以下这些回答可能会对您有所帮助。

      1. 请在speeding up rbind 上查看这个答案,了解为什么它很慢并且不使用循环。它还具有预先分配数据帧的代码。另请参阅 jorans Second circle of hell comment

      2. 建议 rbind.fill 来自@coanil

        我想补充两点:1)一般情况下,如果你不想使用data.table,你可以使用Hadley的plyr包中的rbind.fill函数,速度也很快。永远不要像上面那样在“for”循环中使用 rbind,分别附加每一行。每次追加一行时,它都会强制 R 复制数据框对象,这很慢。

      https://stackoverflow.com/a/19699342/4606130

      1. 如果你走data.table路线,那么使用更快的rbindlist。 (@David 在第一个答案链接中建议了这一点。)

      【讨论】:

        【解决方案5】:

        我有一个类似的问题,我想使用dplyr 以整洁的方式解决它。我最终使用dplyr::filter()dplyr::row_number() 根据行号从我的数据框中过滤了指定的行。并使用dplyr::bind_rows() 将它们绑定到原始数​​据帧,所有这些都在一个管道中。在您的示例中,它将是这样的:

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

        如果您想复制特定的行,快速简单!当然,您可以使用特定的行号进行复制,使用filter(row_number() %in% c(...))

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-03
          • 1970-01-01
          • 2013-08-14
          • 2016-11-02
          • 1970-01-01
          • 1970-01-01
          • 2014-10-07
          相关资源
          最近更新 更多