我运行了以下代码,这需要我很长时间才能运行。我怎么知道它是否还在做它的工作还是卡在某个地方。
noise4<-NULL;
for(i in 1:length(noise3))
{
if(is.na(noise3[i])==TRUE)
{
next;
}
else
{
noise4<-c(noise4,noise3[i]);
}
}
noise3是具有2418233个数据点的向量。
答案 0 :(得分:10)
您只想删除NA值。这样做:
noise4 <- noise3[!is.na(noise3)]
这几乎是即时的。
或者约书亚建议,一个更具可读性的选择:
noise4 <- na.omit(noise3)
你的代码很慢,因为:
内存重新分配可能是您代码的最大障碍。
答案 1 :(得分:5)
我想说明预分配的好处,所以我试着运行你的代码......但是我在约5分钟后杀了它。我建议您使用noise4 <- na.omit(noise3)
,正如我在评论中所说的那样。此代码仅用于说明目的。
# Create some random data
set.seed(21)
noise3 <- rnorm(2418233)
noise3[sample(2418233, 100)] <- NA
noise <- function(noise3) {
# Pre-allocate
noise4 <- vector("numeric", sum(!is.na(noise3)))
for(i in seq_along(noise3)) {
if(is.na(noise3[i])) {
next
} else {
noise4[i] <- noise3[i]
}
}
}
system.time(noise(noise3)) # MUCH less than 5+ minutes
# user system elapsed
# 9.50 0.44 9.94
# Let's see what we gain from compiling
library(compiler)
cnoise <- cmpfun(noise)
system.time(cnoise(noise3)) # a decent reduction
# user system elapsed
# 3.46 0.49 3.96
答案 2 :(得分:4)
其他答案为您提供了更多,更好的方法来完成您实际要实现的任务(删除数据中的NA
值),但回答了您提出的具体问题(“如何我是否知道R是否实际正在工作或是否已经卡住?“)是在循环中引入一些输出(cat
)语句,如下所示:
rpt <- 10000 ## reporting interval
noise4<-NULL;
for(i in 1:length(noise3))
{
if (i %% rpt == 0) cat(i,"\n")
if(is.na(noise3[i])==TRUE)
{
next;
}
else
{
noise4<-c(noise4,noise3[i]);
}
}
如果您运行此代码,您可以立即看到它在循环中越来越慢(未能预先分配空间的结果)...
答案 3 :(得分:2)
其他人都有正确的方法来解决同样的问题,所以你不必担心速度。 @BenBolker也提供了关于常规输出的好指针。
另一件需要注意的事情是,如果你发现自己处于循环中,你可以突破它并找到i
的值。假设从i
的值重新开始不会损害事物,即使用该值两次不会有问题,您可以重新启动。或者,您可以像其他人所说的那样完成工作。
另一个技巧是,如果循环缓慢(并且无法进行矢量化,或者您不想急于退出循环), AND 您没有任何报告,您仍然可以查找外部方法,以查看R是否实际消耗了计算机上的周期。在Linux中,top
命令是您最好的选择。在Windows上,任务管理器将执行操作(我更喜欢使用SysInternals / Microsoft程序Process Explorer)。 “顶级”也存在于Mac上,但我相信还有一些其他更受欢迎的工具。
另一个建议是:如果你有一个很长的循环运行,我强烈建议定期保存结果。我通常创建一个名称为myPrefix_YYYYMMDDHHMMSS.rdat
的文件。这样一切都可以下地狱,你仍然可以从你离开的地方开始循环。
我并不总是迭代,但是当我这样做时,我会使用这些技巧。保持快速,我的朋友。