矢量化/data.table-提高12kk记录的for循环效率

矢量化/data.table-提高12kk记录的for循环效率,r,loops,data.table,vectorization,R,Loops,Data.table,Vectorization,我需要将该组关联到2万个组,总共有1200万行 为了解决这个问题,我写了一个for循环,但它显然是完全低效的,我相信这个任务可以很容易地矢量化。然而,我正在努力理解如何以矢量化的方式编写此指令 问题如下: 我有一个辅助表格,有3个功能:ID、开始行、结束行。 start_row是my_DF中属于ID x的第一个元素的行索引 end_row是my_DF中属于ID x的最后一个元素的行索引 矢量化指令应执行以下操作: 考虑如下所示的辅助_表: auxiliary_table <- data.f

我需要将该组关联到2万个组,总共有1200万行

为了解决这个问题,我写了一个for循环,但它显然是完全低效的,我相信这个任务可以很容易地矢量化。然而,我正在努力理解如何以矢量化的方式编写此指令

问题如下: 我有一个辅助表格,有3个功能:ID、开始行、结束行。
start_row是my_DF中属于ID x的第一个元素的行索引
end_row是my_DF中属于ID x的最后一个元素的行索引

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

考虑如下所示的辅助_表:

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)

auxiliary_table我设计了一个用户定义的函数,并将其应用于
auxiliary_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

auxiliary_table我设计了一个用户定义的函数,并将其应用于
auxiliary_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

辅助表辅助表
是一种行程编码。因此,我建议使用经过适当转换的辅助表来尝试
inverse.rle()
函数:

1.dplyr 2.数据表 这将添加
ID
列,而不复制
my_df

library(data.table)
setDT(my_df)[, ID := inverse.rle(setDT(auxiliary_table)[
  , .(lengths = end_row - start_row + 1L, values = ID)])][]
根据
辅助_表
的大小,下面的代码可能更有效,因为它将
辅助_表
转换到位:


辅助_表
是一种行程编码。因此,我建议使用经过适当转换的辅助表来尝试
inverse.rle()
函数:

1.dplyr 2.数据表 这将添加
ID
列,而不复制
my_df

library(data.table)
setDT(my_df)[, ID := inverse.rle(setDT(auxiliary_table)[
  , .(lengths = end_row - start_row + 1L, values = ID)])][]
根据
辅助_表
的大小,下面的代码可能更有效,因为它将
辅助_表
转换到位:



如果有一些数据的例子,我将不胜感激;输入是什么样子的,输出应该是什么样子的lke…很抱歉,我忘了将我的_-df格式化为代码,但是,我展示了我的_-df,用于索引我的_-df和表示任务解决方案的解决方案的solution-df的辅助_表。如果我还需要介绍其他东西吗?如果有一些数据的例子,我将不胜感激;输入是什么样子的,输出应该是什么样子的lke…很抱歉,我忘了将我的_-df格式化为代码,但是,我展示了我的_-df,用于索引我的_-df和表示任务解决方案的解决方案的solution-df的辅助_表。我是否应该介绍其他内容?不幸的是,apply函数的效率并不比使用for循环执行相同的操作更高。您可能希望使用
as.matrix()
强制转换它,这可能会有所帮助。除此之外,您所能做的事情不多。我想我确信有一种非常有效的方法可以做到这一点。不幸的是,应用函数的效率并不比使用for循环执行相同的操作更高。您可能希望使用
as.matrix()
强制转换它,这可能会有所帮助。除此之外,你没什么办法,我想我相信有一种非常有效的方法可以做到这一点,非常感谢。我发现难以学习的数据表,您是否有任何材料/网站建议我理解如何编写这篇非常有用的文章?一个很好的起点是
Data.Table
主页上提供的链接,特别是小插曲。如果你对SQL有一定的了解,这会很有帮助。非常感谢你,你不知道你帮了我多少忙!我在一个类似的任务中应用了你的算法。新任务之间的区别在于,有时
start\u row==end\u row
,因此,在这种情况下,
ID
必须仅与
row.number==start\u row==end\u row
的一个元素相关联。但是,我收到了以下问题:
提供了16449900个项目,分配给“ID”列的1381231个项目(2637769未使用)
Hmm,如果长度为1(
start\u row==end\u row
),则
inverse.rle()
也应该工作。因此,我怀疑其他数据集存在另一个问题。请发布一个新问题,显示其他数据。非常感谢。我发现难以学习的数据表,您是否有任何材料/网站建议我理解如何编写这篇非常有用的文章?一个很好的起点是
Data.Table
主页上提供的链接,特别是小插曲。如果你对SQL有一定的了解,这会很有帮助。非常感谢你,你不知道你帮了我多少忙!我在一个类似的任务中应用了你的算法。新任务之间的区别在于,有时
start\u row==end\u row
,因此,在这种情况下,
ID
必须仅与
row.number==start\u row==end\u row
的一个元素相关联。但是,我收到了以下问题:
提供了16449900个项目,分配给“ID”列的1381231个项目(2637769未使用)
Hmm,如果长度为1(
start\u row==end\u row
),则
inverse.rle()
也应该工作。因此,我怀疑其他数据集存在另一个问题。请发布一个显示其他数据的新问题。
library(data.table)
setDT(my_df)[, ID := inverse.rle(setDT(auxiliary_table)[
  , .(lengths = end_row - start_row + 1L, values = ID)])][]
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")])][]