R动态行插入循环性能

时间:2016-12-06 16:17:15

标签: r

在清理脏数据集时,我的最后一步是为每个"类型"构建一组具有一定数量的管道分隔符的虚拟行。每个record_numb的行(uptopipe)。我已经阅读了相当多的内容并且已经开始工作了,但是我想看看你们中的任何一位专家是否有更有效的处理方法让我尝试。

此表显示每个记录需要为每种类型生成多少个虚拟行:

uptopipe <- c("A","B","C")
empty_rows_needed <- c(4,3,2)
pipes <- c('|||||','||','|||||||')
record_numb <- c(1,1,1)
rows_to_make <- data.frame(record_numb, uptopipe, empty_rows_needed, pipes)
rows_to_make$row_numb <- rownames(rows_to_make)

record_numb          uptopipe   empty_rows_needed pipes     row_numb
1                    A          4                 |||||     1
1                    B          3                 ||        2
1                    C          2                 |||||||   3

对于我的例子,我只会显示1个record_numb,但是我需要遍历几个record_numb值。 我有一个单独的表格,其中包含我需要附加的所有记录:

record_numb <-  c(1,1,1)
uptopipe   <-  c("A","A","B")
V1     <-    c("Alah|||||","Alah|||||","Blah||")
my_data <- data.frame(record_numb , uptopipe, V1)

 record_numb  uptopipe   V1
           1         A   Alah|||||
           1         A   Alah|||||
           1         B   Blah||

我的目标是使每个record_number具有相同数量的A,B和C行。我需要插入的行应该只有我创建的空行的管道。 &#34; A&#34;有2条记录,需要4个假人 &#34; B&#34;有1条记录,需要3个假人 &#34; C&#34;有0条记录,需要2个假人

虚拟输出应如下所示:

record_numb     uptopipe    V1
          1            A    |||||
          1            A    |||||
          1            A    |||||
          1            A    |||||
          1            B    ||
          1            B    ||
          1            B    ||
          1            C    |||||||
          1            C    |||||||

我的方法是创建一个包含所有虚拟记录的单独数据框(my_new_rows),然后将其绑定到单独数据框中的现有良好记录。我尝试了4种方法来制作假人,所有这些都有效,但性能很糟糕。这是我尝试过的:

方法1:

  #make dataframe shell
  my_new_rows <- data.frame(record_numb=integer(), uptopipe=character(), V1=character(), stringsAsFactors=FALSE)

for (i in 1:nrow(rows_to_make)) {
        for (j in 1:subset(rows_to_make,row_numb==i)$empty_rows_needed){
          my_new_rows <- rbind(my_new_rows,data.frame(record_numb=subset(rows_to_make,record_numb==i)$record_numb,
                                                  uptopipe=subset(rows_to_make,record_numb==i)$uptopipe,
                                                  V1=subset(rows_to_make,record_numb==i)$pipes
                                         ))
    }
  }

方法2 - 使用变量并附加

  my_new_rows <- data.frame(record_numb=integer(), uptopipe=character(), V1=character(), stringsAsFactors=FALSE)


  rec_num_1 = NULL
  u2p1      = NULL
  V1_1      = NULL

  for (i in 1:nrow(rows_to_make)) {
    for (j in 1:subset(rows_to_make,row_numb==i)$empty_rows_needed){
  rec_num_1 = append(rec_num_1,subset(rows_to_make,row_numb==i)$record_numb)
  u2p1      = append(u2p1,     as.character(subset(rows_to_make,row_numb==i)$uptopipe))
  V1_1      = append(V1_1,     as.character(subset(rows_to_make,row_numb==i)$pipes))
  }}   #takes a while -- 30 mins?
  my_new_rows <- data.frame(rec_num_1,u2p1,V1_1)

我已经尝试过使用sqldf / sprintf的其他一些方法,但这比这些方法还慢。

我正在创建大约120k的虚拟记录,每种方法花费近一个小时。

有人可以提出一种更有效的方法来生成虚拟记录吗?

1 个答案:

答案 0 :(得分:0)

我们可以使用rep复制第三列的行序列,然后使用该索引展开数据集

df1 <- rows_to_make[rep(1:nrow(rows_to_make), rows_to_make[,3]),][c(1,2,4)]
row.names(df1) <- NULL
df1