我在R中遇到了很大的性能问题.我编写了一个迭代data.frame对象的函数.它只是添加一个新列data.frame并积累一些东西.(操作简单).将data.frame有大约850K行.我的电脑仍在工作(现在大约10小时),我不知道运行时间.
dayloop2 <- function(temp){
for (i in 1:nrow(temp)){
temp[i,10] <- i
if (i > 1) {
if ((temp[i,6] == temp[i-1,6]) & (temp[i,3] == temp[i-1,3])) {
temp[i,10] <- temp[i,9] + temp[i-1,10]
} else {
temp[i,10] <- temp[i,9]
}
} else {
temp[i,10] <- temp[i,9]
}
}
names(temp)[names(temp) == "V10"] <- "Kumm."
return(temp)
}
Run Code Online (Sandbox Code Playgroud)
有什么想法如何加快这个操作?
我第一次尝试了Rcpp功能inline,它解决了我的速度问题(感谢Dirk!):
R:将负值替换为零
初始版本看起来像这样:
library(inline)
cpp_if_src <- '
Rcpp::NumericVector xa(a);
int n_xa = xa.size();
for(int i=0; i < n_xa; i++) {
if(xa[i]<0) xa[i] = 0;
}
return xa;
'
cpp_if <- cxxfunction(signature(a="numeric"), cpp_if_src, plugin="Rcpp")
Run Code Online (Sandbox Code Playgroud)
但是当被调用时cpp_if(p),它会p用输出覆盖,这不是预期的.所以我认为它是通过引用传递的.
所以我用以下版本修复它:
library(inline)
cpp_if_src <- '
Rcpp::NumericVector xa(a);
int n_xa = xa.size();
Rcpp::NumericVector xr(a);
for(int i=0; i < n_xa; i++) {
if(xr[i]<0) xr[i] = 0;
}
return xr;
'
cpp_if <- cxxfunction(signature(a="numeric"), cpp_if_src, plugin="Rcpp")
Run Code Online (Sandbox Code Playgroud)
这似乎有效.但是现在,当我将其重新加载到R中时,原始版本不再覆盖其输入(即,相同的确切代码现在不会覆盖其输入):
> cpp_if_src <- '
+ Rcpp::NumericVector …Run Code Online (Sandbox Code Playgroud) 我有一个矢量
x <- c(-1, 0, 1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
我希望所有小于1的值都替换为1.
怎么样?
有无循环解决方案吗?
我在R中写了一个Gibbs采样器并决定将它移植到C以查看它是否会更快.我看过很多页面声称C的速度会快50倍,但每次使用它时,它只比R快了大约五六倍.我的问题是:这是预期的,还是我没有使用哪些技巧会使我的C代码明显快于此(就像使用矢量化加速R中的代码一样)?我基本上接受了代码并在C中重写了它,用for循环替换矩阵操作并使所有变量指针.
另外,从R程序员的角度来看,有没有人知道C的良好资源?Matloff 有一本名为The Art of R Programming的优秀书籍,但它似乎是从已经知道C.的人的角度写的.
此外,当我的C代码在Windows的标准R GUI中运行时,屏幕会冻结.它没有崩溃; 一旦代码完成运行,它就会解冻,但它阻止我在GUI中做任何其他事情.有谁知道我怎么能避免这个?我正在使用.C()调用该函数
我来自 Python 的世界。我只想获取正数并将非正数设置为零。在 Python 中:
>> a = [1,2,3,-1,-2, 0,1,-9]
>> [elem if elem>0 else 0 for elem in a]
[1, 2, 3, 4, 0, 0, 0, 1, 0]
Run Code Online (Sandbox Code Playgroud)
假设我在 R 中有一个向量,我怎样才能得到相同的结果。
a <- c(1,2,3,-1,-2, 0,1,-9)
Run Code Online (Sandbox Code Playgroud)