2

可能重复:
为什么循环在 R 中很慢?

考虑以下任务。一个数据集有 20,000 个“用户”的 40 个变量。每个用户有 1 到 150 个观察值。所有用户都堆叠在一个称为数据的矩阵中。第一列是用户的 id,用于标识用户。所有 id 都存储在称为 userid 的 20,000 X 1 矩阵中。

考虑以下 R 代码

useridl = length(userid)
itime=proc.time()[3]    
for (i in 1:useridl) {
temp =data[data[,1]==userid[i],]
   }
 etime=proc.time()[3]
 etime-itime

这段代码只经过 20,000 个用户,每次都创建临时矩阵。使用属于 userid[i] 的观察子集。在 MacPro 中大约需要 6 分钟。

在 MatLab 中,同样的任务

tic
for i=1:useridl
temp=data(data(:,1)==userid(i),:);
end
toc

需要 1 分钟。

为什么R这么慢?这是标准任务,我在这两种情况下都使用矩阵。有任何想法吗?

4

1 回答 1

6

正如@joran 评论的那样,这是不好的 R 实践。lapply无需重复对原始矩阵进行子集化,只需将子集放在列表中一次,然后使用或类似方法遍历列表。

# make example data
set.seed(21)
userid <- 1:1e4
obs <- sample(150, length(userid), TRUE)
users <- rep(userid, obs)
Data <- cbind(users,matrix(rnorm(40*sum(obs)),sum(obs),40))

# reorder so Data isn't sorted by userid
Data <- Data[order(Data[,2]),]
# note that you have to call the data.frame method explicitly,
# the default method returns a vector
system.time(temp <- split.data.frame(Data, Data[,1])) ## Returns times in seconds
#    user  system elapsed 
#    2.84    0.08    2.92 

我的猜测是垃圾收集器正在减慢你的 R 代码,因为你不断地覆盖temp对象。

于 2012-10-30T16:04:57.767 回答