【发布时间】:2016-02-03 13:36:43
【问题描述】:
我还是 R 编程新手,我需要优化我的部分代码。我将在下面解释它是如何工作的。
我当前的代码太慢了
myfunc <- function(dt){
indexes = which(dt$time == CURRENT)
for(i in indexes){
# columns foo, bar & baz are used to build rowname
# and colnames
linename = paste(dt$foo[i], "_", dt$bar[i], sep="")
colname = dt$baz[i]
# related_var is the name of an other global var
# and value is the corresponding value in
# related_var[linename, colname]
dt$value[i] = get(dt$related_var[i])[[linename, colname]]
}
return(dt)
}
如何使用它?
这不是我的代码部分,所以我只是简化了它
CURRENT = 0
MAX = 1000
for(i in 1:MAX){
doSomeStuffOnGlobalVars()
# get datas from global var for this CURRENT
dt = myfunc(dt)
CURRENT = CURRENT + 1
}
一些解释
为CURRENT (like 1,2,3,4,5,... 1000) 的所有值调用此函数,我们希望为匹配dt$time == CURRENT 的每一行更新dt 中的$value,问题是变量“varname”每CURRENT 修改一次
dt : a data.table ordered by time in the form of
foo bar baz time related_var value
1 1 "toto" 1 "varname" NA
1 2 "toto" 1 "varname" NA
2 1 "tata" 1 "varname" NA
2 8 "toto" 1 "varname" NA
...
related_var : contain the name of a global data.frame which have its
colnames defined by baz in dt
rownames defined by a combination of foo & bar (foo_bar) in dt
example of "varname" variable:
toto tata
1_1 1.6 2
1_2 42 1337
... ... ...
10_10 3.14 1.61
我已经进行了一些更改(我在data.table 或eval(parse(...)) 之前使用了data.frame)但这仍然很慢(大约 5 秒的 dt 大约 5000 行),我想知道我该怎么做优化这个,如果你有想法(R 或纯算法)
注意告诉我它是否太神秘了
编辑:我发现较慢的部分是dt$value[i] = get(dt$related_var[i])[[linename, colname]],如果我进行像justAvar = get(dt$related_var[i])[[linename, colname]] 这样的简单分配,它会变得更快,所以我现在的问题是:“R 是如何通过索引的?如果我想go to index=15 R 会遍历所有 14 个之前的元素吗?”
【问题讨论】:
-
乍一看,我认为您可以将这个 -
linename = paste(dt$foo[i], "_", dt$bar[i], sep="")- 移到循环之外,因为paste和[是矢量化的。并且与优化无关,但将CURRENT作为参数传递给myfunc会更惯用,而不是根据范围规则在父环境中找到它。 -
据我所知,您根本不需要函数内部的
for循环(最后一条语句可能是可能,但即使这样也可以使用向量化mget和lapply的组合。
标签: r performance optimization comparison