我在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)
有什么想法如何加快这个操作?
学习如何编写用于R的C代码的最佳资源是什么?我知道R扩展的系统和外语接口部分,但我发现它很难.编写用于R的C代码有哪些好的资源(在线和离线)?
为了澄清,我不想学习如何编写C代码,我想学习如何更好地集成R和C.例如,我如何从C整数向量转换为R整数向量(反之亦然)或者从C标量到R向量?
我一直在阅读read.table如何对大数据文件无效.R也不适用于大型数据集.所以我想知道在哪里可以找到实际限制和任何性能图表(1)读取各种尺寸的数据(2)处理不同大小的数据.
实际上,我想知道性能何时恶化以及何时遇到路障.对C++/MATLAB或其他语言的任何比较都会非常有用.最后如果Rcpp和RInside有任何特殊的性能比较,那就太棒了!
我想了解在设置宏/变量的作用和关系,~/.R/Makevars以及package_directory/src/Makevars安装时/构建自己的R包.假设这些文件看起来像
〜/ .R/Makevars
CXX = g++
CXXSTD = -std=c++11
CXXFLAGS = -fsanitize=undefined,address -fno-omit-frame-pointer
CXX98 = g++
CXX98STD = -std=c++98
CXX11 = g++
CXX11STD = -std=c++11
CXX14 = g++
CXX14STD = -std=c++14
Run Code Online (Sandbox Code Playgroud)
package_directory/SRC/Makevars
PKG_CPPFLAGS = -I../inst/include
CXX_STD = CXX11
Run Code Online (Sandbox Code Playgroud)
据我所知,CXX我们可以在构建R包时为C++选择编译器,CXXSTD我们选择标准并CXXFLAGS添加编译器标志.随着PKG_CPPFLAGS我们为C++预处理器添加标志,CXX_STD我们告诉我们的包使用C++ 11.
我有以下问题:
CXX和CXX98,CXX11和CXX14?CXX11STD = -std=c++11如果已经隐含了C++ 11,那意味着什么?是在选择-std=c++11和-std=gnu++11?应该-std=gnu++11通常避免针对便携性的原因?CXXSTD,CXXFLAGS …当我尝试时sourceCpp,它会发出警告:
ld:警告:基于文本的存根文件/System/Library/Frameworks//CoreFoundation.framework/CoreFoundation.tbd和库文件/System/Library/Frameworks//CoreFoundation.framework/CoreFoundation不同步.回到库文件进行链接.
但功能确实有效.只是想知道如何解决这个警告.
我有一个名为的头文件coolStuff.h包含一个awesomeSauce(arg1)我想在我的cpp源文件中使用的函数.
目录结构:
代码:
#include <Rcpp.h>
#include <cppHeaders/coolStuff.h>
using namespace Rcpp;
// [[Rcpp::export]]
double someFunctionCpp(double someInput){
double someOutput = awesomeSauce(someInput);
return someOutput;
}
Run Code Online (Sandbox Code Playgroud)
我收到错误:
theCppFile.cpp:2:31: error: cppHeaders/coolStuff.h: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我已经移动了整个地方的文件和目录,似乎无法让它工作.我看到使用第三方标题的示例,只是说这样做:
#include <boost/array.hpp>
Run Code Online (Sandbox Code Playgroud)
(来自Hadley/devtools)
https://github.com/hadley/devtools/wiki/Rcpp
什么给出了什么?我整个上午一直在寻找,但找不到像我这样简单事情的答案.
好了,我已经想出如何在Rstudio中构建使用Rcpp的软件包,让我重新解释一下这个问题.我有一个独立的头文件coolStuff.h,它包含我想在我的cpp代码中使用的函数.
1)我应该在包目录结构中放置coolStuff.h,以便它包含的函数可以被CppFile.cpp使用?
2)如何在cpp文件中调用coolStuff.h?再次感谢你的帮助.我从上次谈话中学到了很多东西.
注意:我阅读了小插图"编写使用Rcpp的软件包",但没有解释如何执行此操作.
好吧,让我总结一下我的问题的答案,因为它分散在这个页面上.如果我得到一个错误的细节,请随时编辑或让我知道,我将编辑它:
因此,您找到了一个.h或多个.cpp文件,其中包含您要在.cpp要编写的文件中使用的函数或其他一些代码Rcpp.
让我们继续调用这个找到的代码coolStuff.h并调用你想要使用的函数awesomeSauce().让我们调用您正在编写的文件theCppFile.cpp.
(我应该注意这里.h文件和.cpp文件中的代码都是C++代码,它们之间的区别在于C++程序员以正确的方式保持组织.我将在这里讨论差异,但在SO上进行简单的搜索会引导你讨论差异.对于你需要使用你发现的代码的R程序员,没有真正的区别.)
简而言之:您可以使用一个文件,coolStuff.h如果它不调用其他库,通过剪切和粘贴theCppFile.cpp,或者如果您创建一个包,您可以将文件放在\src包含该theCppFile.cpp文件的目录中并在文件 …
考虑以下R代码,
## ----------- R version -----------
caller <- function(x=1:3, fun = "identity", ...){
## do some other stuff
## ...
## then call the function
eval(call(fun, x))
}
fun1 <- function(x, ...){
x + x
}
fun2 <- function(x, a = 10) a * x
caller(fun = "fun1")
caller(fun = "fun2")
Run Code Online (Sandbox Code Playgroud)
用户可以传递函数名称"fun" caller.我希望用RcppArmadillo对象执行相同的任务(显然是一个更复杂的任务的一部分).该函数将被定义C++,并且用户通过引用其名称在R级别选择它:
caller_cpp(1:3, "fun1_cpp")
Run Code Online (Sandbox Code Playgroud)
要么
caller_cpp(1:3, "fun2_cpp")
Run Code Online (Sandbox Code Playgroud)
等等
这是我对调用函数的天真尝试,甚至无法编译:
## ----------- C++ version -----------
library(Rcpp)
require( RcppArmadillo )
sourceCpp( code = '
// [[Rcpp::depends("RcppArmadillo")]] …Run Code Online (Sandbox Code Playgroud) 我一直在尝试创建一个数据库并安装了“DBI”包,但仍然面临这个错误。我重新安装了 DBI 和 RSQLite 包,但它们似乎不起作用。
con <- dbConnect
(RSQLite::SQLite(), dbname = ":memory:")
dbListTables(con)```
Error :Error in connection_connect(dbname, loadable.extensions, flags, vfs, extended_types) : function 'Rcpp_precious_remove' not provided by package 'Rcpp'
Run Code Online (Sandbox Code Playgroud) 我正在编写一个Rcpp模块,希望作为RcppResultSet列表的一个元素返回一个列表,其元素是向量.例如,.Call("myfunc")$foo应该是这样的:
[[1]]
[1] 1
[[2]]
[1] 1 1
[[3]]
[1] 1 1 1
Run Code Online (Sandbox Code Playgroud)
(这里确切的数字并不重要).问题是我不知道正确的Rcpp方式.我尝试传递一个vector<vector<int> >但是这通过静默地将第一个向量的长度作为宽度来构造矩阵(即使矩阵是粗糙的!).我已经尝试构建一个RcppList但很难RcppVector安全地将各种对象(例如)投射到SEXPs中.
任何人都有关于处理复杂结构的最佳实践的提示,例如Rcpp中的向量列表?
调试加载到R中的共享对象的最有效和最快捷的方法是什么,特别是在OS X Mavericks上?我主要对调试编译的Rcpp代码感兴趣.
我已经阅读了关于调试编译代码的R外部代码(http://cran.r-project.org/doc/manuals/R-exts.html#Debugging-compiled-code),这有利于使用gdb,但是gdb不是正式的小牛队支持.但是,似乎lldb是一个可行的替代方案吗?我找到了最有用的资源,用于研究如何在Dirk对此帖子的回复中调试R中的编译代码(Thanks Dirk!)(在Windows下调试(逐行)Rcpp生成的DLL).
我可以通过按照下面逐步明确的步骤来成功调试已编译的Rcpp代码,其他Rcpp新手可能会觉得这很有用(道歉的长度,但我认为最好是明确而不是省略和模糊).但是这个开发过程有点繁琐且耗时.
问题:
与我在下面的操作相比,是否有更快速和/或更简单的方法来调试已编译的Rcpp代码?
我是Rstudio的忠实粉丝,并且很乐意合并从该IDE创建的调试共享对象,所以如果有人知道如何做到这一点,我会有兴趣知道吗?Rstudio似乎使用属性,看起来下面的步骤4需要修改,因为编译后在临时目录中似乎没有.cpp文件(在我的示例中,没有"file5156292c0b48.cpp"文件)
步骤:
1)(一次性)转到〜/ .R目录(带有.的隐藏目录).创建一个名为"Makevars"的新文件,然后在其中添加该行CXXFLAGS=-g -O0 -Wall.
2)在终端中,键入R -d lldb以启动R. lldb现在将启动.
3)run在lldb命令行输入.这将启动R.
4)编译Rcpp代码并找到编译对象的位置.德克对上述帖子的回应显示了一种方法.这是我将在这里使用的一个例子.在R中运行以下命令:
library(inline)
fun <- cxxfunction(signature(), plugin="Rcpp", verbose=TRUE, body='
int theAnswer = 1;
int theAnswer2 = 2;
int theAnswer3 = 3;
double theAnswer4 = 4.5;
return wrap(theAnswer4);
')
Run Code Online (Sandbox Code Playgroud)
这将创建一个编译的共享对象和其他文件,可以通过在R中运行setwd(tempdir())和list.files()来找到.将有一个.cpp文件,如"file5156292c0b48.cpp"和.so文件,如" file5156292c0b48.so"
5)通过dyn.load("file5156292c0b48.so")在R命令行运行将共享对象加载到R中
6)现在我们要调试这个.so对象中的C++代码.点击回到lldb ctrl + c.现在我想在file5156292c0b48.cpp文件中的特定行设置一个断点.我通过打开另一个终端并查看file5156292c0b48.cpp中感兴趣的行号来找到正确的行号.假设它是第31行,它对应于theAnswer = 1中的行; 以上在我的例子中.然后我在lldb命令行输入:breakpoint set -f file5156292c0b48.cpp -l 31.调试器打印回来已设置断点和其他一些东西......
7)通过cont在lldb中运行返回到R (在我按下回车之前,R提示不会自动出现)并调用该函数. …