我需要将组与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