R数据结构上的操作效率

R数据结构上的操作效率,r,performance,R,Performance,我想知道是否有关于R中操作效率的文档,特别是那些与数据操作相关的文档 例如: 我认为向数据框中添加列是有效的,因为我猜您只是在向链表中添加一个元素 我认为添加行的速度较慢,因为向量是在C级别的数组中保存的,您必须分配一个长度为n+1的新数组,并复制所有元素 开发人员可能不想将自己绑定到某个特定的实现上,但最好有一些比猜测更可靠的东西 另外,我知道主要的R性能提示是尽可能使用向量化操作,而不是循环 应用的各种风格如何 这些只是隐藏循环吗 那么矩阵与数据帧相比呢 这些东西确实会在列表中弹出,特

我想知道是否有关于
R
中操作效率的文档,特别是那些与数据操作相关的文档

例如:

  • 我认为向数据框中添加列是有效的,因为我猜您只是在向链表中添加一个元素
  • 我认为添加行的速度较慢,因为向量是在
    C级别的数组中保存的,您必须分配一个长度为
    n+1
    的新数组,并复制所有元素
开发人员可能不想将自己绑定到某个特定的实现上,但最好有一些比猜测更可靠的东西

另外,我知道主要的
R
性能提示是尽可能使用向量化操作,而不是
循环

  • 应用<代码>的各种风格如何
  • 这些只是
    隐藏循环吗
    
  • 那么
    矩阵
    数据帧
    相比呢

这些东西确实会在列表中弹出,特别是在r-devel上。一个相当成熟的金块是,
matrix
操作往往比
data.frame
操作更快。还有一些附加软件包做得很好——Matt的软件包非常快,Jeff的索引速度也很快


但这“完全取决于”——因此,通常建议您根据特定代码进行评测
R
有很多评测支持,所以您应该使用它。我的团队有许多评测示例

我会尽量回来提供更多细节。如果您对一个操作相对于另一个操作的效率有任何疑问,您最好分析自己的代码(正如Dirk所建议的)。
system.time()
函数是实现这一点的最简单方法,尽管还有许多更高级的实用程序(例如,如文档所述的Rprof)

快速回答问题的第二部分:

各种口味的苹果怎么样?那些只是隐藏的循环吗

在大多数情况下是的,apply函数只是循环,可能比
语句的
慢。它们的主要好处是代码更清晰。我发现的主要例外是
lappy
,它可以更快,因为它是直接用C编写的

那么矩阵和数据帧呢

矩阵比数据帧更有效,因为它们需要更少的存储内存。这是因为数据帧需要额外的属性数据。发件人:

出于许多目的,数据帧可被视为具有可能具有不同模式和属性的列的矩阵


在我开始学习R之前,数据IO是我研究过的功能之一。不管是好是坏,以下是我对这些问题的观察结果和解决方案/缓解措施:

1.认为R不能处理大数据(>2GB?)对我来说,这是一个误称。默认情况下,通用数据输入函数将数据加载到RAM中。我不想油嘴滑舌,但对我来说,这是一个功能而不是一个bug——任何时候我的数据都可以放入可用的RAM中,这就是我想要的。类似地,SQLite最流行的特性之一是内存选项——用户可以轻松地将整个dB加载到RAM中。如果您的数据无法放入内存,那么R可以通过连接到常见的RDBMS系统(RODBC、RSQLite、RMySQL等),通过像filehash包这样的无装饰选项,以及通过当前技术/实践(例如,我可以推荐)的系统,使数据的持久化变得异常容易。换句话说,R开发人员选择了一个合理的(可能是最优的)默认值,从中很容易选择退出

2。read.table(read.csv,read.delim,et al.)是将数据输入R的最常见的方法,它的性能可以提高5倍(根据我的经验,通常会更高),只需选择几个read.table的默认参数——对性能影响最大的参数在R的帮助(?read.table)中提到。简单地说,R开发人员告诉我们,如果您为参数“colClasses”、“nrows”、“sep”和“comment.char”提供值(特别是,如果您知道文件以标题或第1行的数据开头,则传入“”),您将看到显著的性能提升。我发现那是真的

以下是我用于这些参数的代码段:

要获取数据文件中的行数(在对read.table的调用中,将此代码段作为参数“nrows”的参数提供):

要获取每列的类,请执行以下操作:

function(fname){sapply(read.table(fname, header=T, nrows=5), class)}  
注意:您不能将此代码段作为参数传入,必须先调用它,然后传入返回的值——换句话说,调用函数,将返回的值绑定到变量,然后将变量作为值传入read.table调用中的参数“colClasses”:

as.numeric((gsub("[^0-9]+", "", system(paste("wc -l ", file_name, sep=""), intern=T))))
3。使用扫描。只需要稍微多一点麻烦,您就可以通过使用“scan”而不是“read.table”来做得更好(优化“read.table”)(“read.table”实际上只是“scan”的包装器)。再一次,这是很容易做到的。我使用“scan”分别输入每一列,然后在R中构建data.frame,即df=data.frame(cbind(col1,col2,…)

4。使用R的容器代替普通文件格式(如“txt”、“csv”)进行持久化。R的本机数据文件'.RData'是一种二进制格式,比压缩('.gz')txt数据文件小一点。您可以使用保存(,)创建它们。使用load()将其加载回R名称空间。与“read.table”相比,加载时间的差异是巨大的。例如,w/a 25 MB文件(未压缩大小)

5。关注数据类型通常可以提高性能并减少内存占用。这一点在从R中获取数据时可能更有用
system.time(read.table("tdata01.txt.gz", sep=","))
=>  user  system elapsed 
    6.173   0.245   **6.450** 

system.time(load("tdata01.RData"))
=> user  system elapsed 
    0.912   0.006   **0.912**