当您使用c()连接R中的两个向量时,它"将参数和结果合并为一个向量".它是通过创建一个新的向量来组合它们,以承担两个向量的元素,还是有一种方法可以真正地组合为这两个向量分配的数据空间?

当我搜索它时,我找不到解释,但c()的可视化表示实际上只是将第二个向量附加到第一个向量的末尾,但我认为这只是为了让我们可以很容易地理解这个函数的作用,而不是实际发生的事情.

我是新来的R,所以任何帮助将不胜感激!

推荐答案

当您调用c()时,将分配一个new向量,现有向量将合并到其中.在底层C代码中,这种情况会发生here次.

PROTECT(ans = allocVector(mode, data.ans_length));

这看起来可能很浪费,因为我们已经将值写入内存,所以为什么不简单地将指向该内存的几个指针包装起来,并将that称为向量呢?

这有几个原因.

首先,R对向量执行的许多算术和统计操作都是通过迭代连续内存中的元素来完成的.如果元素不是in个连续的内存,这是不可能的.会有很多地址判断步骤,并在内存地址之间跳转,这会使事情变得慢得多.在R之外,出于大致相同的原因,在C或C++中连接向量也是通过分配一个新的向量来完成的.

第二个原因是避免碎片和内存泄漏.如果我们通过连接其他向量的子集来创建一个向量,而不分配专用内存,我们最终会得到一堆指向内存空闲存储中不同位置的指针.如果我们然后使用this个向量的子集,我们将会有一个噩梦:内存指针指向指向向量片段的内存指针,以及垃圾收集器无法重用或回收的未使用的向量片段块.

第三个原因是,R用户期望修改时复制行为.例如,如果我们有:

a <- c(1, 2, 3)

b <- c(a, a)

b
#> [1] 1 2 3 1 2 3

然后,我们希望能够更改单个元素:

b[6] <- 6

b
#> [1] 1 2 3 1 2 6

然而,如果b没有分配它自己的数据,这个操作将改变b的第三个元素以及第六个元素.


从概念上讲,R中的内存分配是这样的:每个R对象都存储在C中作为SEXP对象.这是一个基本上是指向数据本身的指针的 struct ,它作为一个称为SEXPREC的 struct 存储在内存中.

因此,如果我们运行代码:

A <- 1:4
B <- 5:14

向量AB可以如下存储在存储器中:

enter image description here

如果我们这样做了

C <- c(A, B)

然后在内存中,我们得到:

enter image description here

其中C指向的SEXPREC中的数据是从AB指向的另外两个SEXPREC对象中的数据复制的

R相关问答推荐

使用预定值列表将模拟数量(n)替换为rnorm()

在位置周围设定一个半径并识别该半径内的其他位置

如何使用R Shiny中的条件面板仅隐藏和显示用户输入,同时仍允许运行基础计算?

有没有一种方法可以从函数中创建一个值的列表,然后将这些值变成R中的直方图?我一直觉得不行

如何在区分不同条件的同时可视化跨时间的连续变量?

如何改变x轴比例的列在面

如何在观测缺失的地方添加零

在嵌套列表中查找元素路径的最佳方法

有效识别长载体中的高/低命中

比较理论阿尔法和经验阿尔法

Geom_Hline将不会出现,而它以前出现了

识别连接的子网(R-igraph)

正则表达式在第二个管道和第二个T之后拆分R中的列

停止ggplot将多行减少到一行

手动指定从相同数据创建的叠加图的 colored颜色

有没有办法定制Plot(allEffects())面板标题?

R -基线图-图形周围的阴影区域

在同一单元格中创建包含整数和百分比的交叉表

在ggplot2图表中通过端点连接点

将日期列从字符转换为日期得到的结果是NAS