r-矢量化/数据.表 - 提高12kk记录DF的循环效率



我需要将组与20K组相关联,总计为12m行。

为了解决这个问题,我为循环写了一个问题,但显然这完全效率低下,我相信此任务很容易被矢量化。但是,我正在努力理解如何以矢量形式编写此说明。

问题是:我有一个具有3个功能的Auxiliary_table:id,start_row,end_row。
start_row是属于id x ;
的my_df中第一个元素的行索引end_row是属于id x 的my_df中最后一个元素的行索引。

矢量化指令应执行以下操作:

考虑以下内容的辅助图:

auxiliary_table <- data.frame(ID = c(1,2,3,4), start_row = c(1,4,8,13), end_row = c(3,7,12,14))

考虑DF如下:

  my_df <- data.frame(Var_a = c(1,2,3,1,2,3,4,6,4,3,1,2,1,1)

我们需要基于start_row和end_row索引信息与auxiliary_table中包含的end_row索引信息相关联。

solution_df是:

solution_df <- data.frame(my_df, ID=(1,1,1,2,2,2,2,3,3,3,3,3,4,4)

我要求进行for循环的矢量化,但我可以向数据开放。表解决方案。

我希望我很清楚并正确提出我的问题。

auxiliary_table运行长度编码。因此,我建议使用适当转换的auxiliary_table尝试inverse.rle()函数:

1。dplyr

library(dplyr)
my_df %>%
  mutate(ID = auxiliary_table %>% 
           transmute(lengths = end_row - start_row + 1L, values = ID) %>% 
           inverse.rle())
   Var_a ID
1      1  1
2      2  1
3      3  1
4      1  2
5      2  2
6      3  2
7      4  2
8      6  3
9      4  3
10     3  3
11     1  3
12     2  3
13     1  4
14     1  4

2。data.table

这添加了ID列而不复制my_df

library(data.table)
setDT(my_df)[, ID := inverse.rle(setDT(auxiliary_table)[
  , .(lengths = end_row - start_row + 1L, values = ID)])][]

根据auxiliary_table的大小,以下代码可能会更有效,因为它会将auxiliary_table 转换为

setDT(my_df)[, ID := inverse.rle(setDT(auxiliary_table)[
  , lengths := end_row - start_row + 1L][
    , c("end_row", "start_row") := NULL][
      , setnames(.SD, "ID", "values")])][]

我已经设计了一个用户定义的函数,并将其应用于auxillary_table。看看这是否有帮助 -

auxiliary_table <- data.frame(ID = c(1,2,3,4), start_row = c(1,4,8,13), end_row = c(3,7,12,14))
my_df <- data.frame(Var_a = c(1,2,3,1,2,3,4,6,4,3,1,2,1,1))
solution_df <- data.frame(my_df, ID=c(1,1,1,2,2,2,2,3,3,3,3,3,4,4))
aux_to_df <- function(aux_row){
  # 1,2,3 can be replaced by column names
  value = aux_row[1]
  start_row = aux_row[2]
  end_row = aux_row[3]
  my_df[start_row:end_row, "ID"] <<- value # <<- means assigning to global out of scope variable
}
apply(auxiliary_table, 1, aux_to_df)
my_df

最新更新