我是R的新手。现在我有一个如下函数:
funItemAverRating = function()
{
itemRatingNum = array(0, itemNum);
print("begin");
apply(input, 1, function(x)
{
itemId = x[2]+1;
itemAverRating[itemId] <<- itemAverRating[itemId] + x[3];
itemRatingNum[itemId] <<- itemRatingNum[itemId] + 1;
}
);
}
在此函数中,输入是一个n*3
的数据框,n
是~6*(10e+7)
的,itemRatingNum
是大小为~3*(10e+5)
的向量。
我的问题是为什么apply
功能这么慢(需要将近一个小时才能完成)?此外,随着函数的运行,它会使用越来越多的内存。但如您所见,变量都是在apply
函数之外定义的。有人可以帮助我吗?
程
它很慢,因为您多次调用高级 R 函数。
你必须对函数进行矢量化,这意味着大多数操作(如<-
或+1
)应该在所有数据向量上计算。
例如,在我看来,itemRatingNum
的频率为 input[[2]]
(input
data.frame
的第二列),可以替换为:
tb <- table(input[[2]]+1)
itemRatingNum[as.integer(names(tb))] <- tb
不要那样做。你遵循的逻辑完全不像R。如果我理解正确,您想将某个输入数据帧中第三列的值添加到某个itemAverRating
向量中。
itemRatingNum
正在做的事情,相当模糊。它最终不会进入全局环境,它只是在循环结束时成为一个充满频率的矢量。当您在函数中定义 itemRatingNum 时,<<-
赋值也会在函数的本地环境中分配它,当函数结束时它将被销毁。
接下来,你应该给你的函数输入,并获得一些输出。如果没有必要,切勿分配给全局环境。你的函数等效于以下函数 - 相当快得多 - 它接受输入并给出输出:
funItemAverRating = function(x,input){
sums <- rowsum(input[,3],input[,2])
sumid <- as.numeric(rownames(sums))+1
x[sumid]+c(sums)
}
根据马雷克斯评论编辑的功能
其工作原理如下:
# make data
itemNum <- 10
set.seed(12)
input <- data.frame(
a1 = rep(1:10,itemNum),
a2 = sample(9:0,itemNum*10,TRUE),
a3 = rep(10:1,itemNum)
)
itemAverRating <- array(0, itemNum)
itemAverRating <- funItemAverRating(itemAverRating,input)
itemAverRating
0 1 2 3 4 5 6 7 8 9
39 65 57 36 62 33 98 62 60 38
如果我尝试您的代码,我会得到:
> funItemAverRating()
[1] "begin"
...
> itemAverRating
[1] 39 65 57 36 62 33 98 62 60 38
这是相同的。如果你想要itemRatingNum,那么只需做:
> itemRatingNum <- table(input[,2])
0 1 2 3 4 5 6 7 8 9
6 11 11 8 10 6 18 9 13 8