如何通过 R 中的手动矢量化提高自定义函数的性能
How to improve performance of custom function with manual vectorisation in R
我有两个数据框:df1 提供给定符号的坐标,df2 提供开始和结束坐标。我需要获取 df2 中每个开始和结束坐标之间的符号序列。
例如:
set.seed(1)
df1 <- data.frame(POS = 1:10000000,
REF = sample(c("A", "T", "G", "C"), 10000000, replace = T))
df2 <- data.frame(start = sample(1:5000000, 10, replace = T),
end = sample(5000001:10000000, 10, replace = T))
我试过使用 for 循环:
system.time( {
df2$seq <- NA
for(i in 1:nrow(coords)){
df2$seq[i] <- paste(ref$REF [ c( which(ref$POS == coords$start[i]) : which(ref$POS == coords$end[i]) ) ], collapse = "")
}
})
并使用手动矢量化:
mongoose <- function(from, to){
string <- paste(
ref$REF [ c( which(ref$POS == from) : which(ref$POS == to) ) ],
collapse = "")
return(string)
}
mongoose_vec <- Vectorize(mongoose, vectorize.args = c("from", "to"))
system.time({
sequences <- mongoose_vec(from = df2$start, to = df2$end)
})
但是,这两种方法的执行速度相似,并且速度不够快,因为我将它们应用到的数据集非常大。有人对如何改进性能有任何建议吗?
矢量化不会显着加快您的任务,因为它只会减少开销,但大部分计算都在循环本身内进行。
您可以采用的一种方法是将 ref
存储为长字符串并使用 substr
函数。
ref2 <- paste0(ref$REF, collapse="")
system.time({
sequences2 <- sapply(1:nrow(coords), function(i) {
substr(ref2, coords$start[i], coords$end[i])
})
})
user system elapsed
0.135 0.010 0.145
您的原始代码:
system.time({
sequences <- mongoose_vec(from = coords$start, to = coords$end)
})
user system elapsed
7.914 0.534 8.461
结果相同:
identical(sequences, sequences2)
TRUE
PS:我假设 df1
是 ref
,df2
是 coords
。
我有两个数据框:df1 提供给定符号的坐标,df2 提供开始和结束坐标。我需要获取 df2 中每个开始和结束坐标之间的符号序列。
例如:
set.seed(1)
df1 <- data.frame(POS = 1:10000000,
REF = sample(c("A", "T", "G", "C"), 10000000, replace = T))
df2 <- data.frame(start = sample(1:5000000, 10, replace = T),
end = sample(5000001:10000000, 10, replace = T))
我试过使用 for 循环:
system.time( {
df2$seq <- NA
for(i in 1:nrow(coords)){
df2$seq[i] <- paste(ref$REF [ c( which(ref$POS == coords$start[i]) : which(ref$POS == coords$end[i]) ) ], collapse = "")
}
})
并使用手动矢量化:
mongoose <- function(from, to){
string <- paste(
ref$REF [ c( which(ref$POS == from) : which(ref$POS == to) ) ],
collapse = "")
return(string)
}
mongoose_vec <- Vectorize(mongoose, vectorize.args = c("from", "to"))
system.time({
sequences <- mongoose_vec(from = df2$start, to = df2$end)
})
但是,这两种方法的执行速度相似,并且速度不够快,因为我将它们应用到的数据集非常大。有人对如何改进性能有任何建议吗?
矢量化不会显着加快您的任务,因为它只会减少开销,但大部分计算都在循环本身内进行。
您可以采用的一种方法是将 ref
存储为长字符串并使用 substr
函数。
ref2 <- paste0(ref$REF, collapse="")
system.time({
sequences2 <- sapply(1:nrow(coords), function(i) {
substr(ref2, coords$start[i], coords$end[i])
})
})
user system elapsed
0.135 0.010 0.145
您的原始代码:
system.time({
sequences <- mongoose_vec(from = coords$start, to = coords$end)
})
user system elapsed
7.914 0.534 8.461
结果相同:
identical(sequences, sequences2)
TRUE
PS:我假设 df1
是 ref
,df2
是 coords
。