Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R中无for循环的就地列表修改_R - Fatal编程技术网

在R中无for循环的就地列表修改

在R中无for循环的就地列表修改,r,R,我想知道是否有一种方法可以在不使用for循环的情况下就地修改列表中的对象。例如,如果列表中的单个对象较大且复杂,因此我们希望避免创建整个对象的临时副本,那么这将非常有用。作为一个例子,考虑下面的代码,该代码创建三个数据帧的列表,然后计算数据的一列的所有三个数据帧的最大值向量,然后将该向量分配给每个原始数据帧。(在ggplot2中对齐绘图时需要这样的代码。) data\u listBase R数据结构通过共享进行复制和修改。以具有三个数字列的data.frame为例。每个data.frame都是一

我想知道是否有一种方法可以在不使用
for
循环的情况下就地修改列表中的对象。例如,如果列表中的单个对象较大且复杂,因此我们希望避免创建整个对象的临时副本,那么这将非常有用。作为一个例子,考虑下面的代码,该代码创建三个数据帧的列表,然后计算数据的一列的所有三个数据帧的最大值向量,然后将该向量分配给每个原始数据帧。(在ggplot2中对齐绘图时需要这样的代码。)


data\u listBase R数据结构通过共享进行复制和修改。以具有三个数字列的data.frame为例。每个data.frame都是一个长度为3的“list”向量,每个都包含对基础列的数字向量的引用。如果修改/替换第一列,R将创建一个新的length 3 data.frame“list”,其中包含对新(ly-modified)列和其他两个未修改列的引用

让我们看看如何使用
address
函数*

set.seed(1)
data_list <- lapply(1:3, function(x) data.frame(x=rnorm(10), y=rnorm(10), z=rnorm(10)))

before <- rapply(data_list,address)
这意味着您不必像想象的那样担心对大型数据结构进行更改。通常,只需替换数据结构的修改部分和骨架。在本例中,无论如何都必须创建
max_x
向量,因此唯一的开销是创建一个新的3单元data.frame“list”,并用3个引用填充它**。但是,如果您迭代地“敲打”更改或使用子向量而不是整个列,那么这可能会变得效率低下。这些是不适用于本例的
data.table
的用例


*此处使用的
address
函数是从
data.table
包导出的


**当然,在本例中,包含3个data.frames的3个单元格外部列表“list”本身。

是什么让你认为整个对象都在复制?@MichaelChirico循环中的第一个赋值似乎是复制:
库(data.table);对于(i in 1:length(data_list)){print(address(data_list));data_list[[i]]]$x@Claus-Wilke:for
循环使用
有什么不对?R将只复制列表结构(3个单元格)这包括data.frame和修改后的列。未修改的列不需要复制--它们是共享的。也就是说,
y
z
列将不会被复制:
library(data.table);for(i in 1:length(data_list)){print(address(data_list[i]$y));data_list[[i]$x不带for循环:
sapply(1:3,函数(y){data_list[[y]]$x值得注意的是,
x
列在被更改之前只有与
max\ux
相同的地址。然后显然必须进行复制。直到它们再次被更改?示例是更改为
max\ux
,因此无需复制,只需更改对
max\ux
的引用。如果没有其他指向ol的话d
x
列,然后它们将接受垃圾收集。我的意思是:
x
set.seed(1)
data_list <- lapply(1:3, function(x) data.frame(x=rnorm(10), y=rnorm(10), z=rnorm(10)))

before <- rapply(data_list,address)
max_x <- do.call(pmax, lapply(data_list, function(d){d$x}))
data_list <- lapply(data_list,`[<-`,"x",value=max_x)    

after <- rapply(data_list,address)
address(max_x)
[1] "05660600"

cbind(before,after)

  before     after     
x "0565F530" "05660600"
y "0565F400" "0565F400"
z "05660AC0" "05660AC0"
x "05660A28" "05660600"
y "05660990" "05660990"
z "05660860" "05660860"
x "056607C8" "05660600"
y "05660730" "05660730"
z "05660698" "05660698"