【发布时间】:2016-03-22 05:27:58
【问题描述】:
我想知道是否有一种方法可以在不使用for 循环的情况下对列表中的对象进行就地修改。这将很有用,例如,如果列表中的单个对象又大又复杂,那么我们希望避免制作整个对象的临时副本。例如,考虑以下代码,该代码创建三个数据帧的列表,然后为一列数据计算所有三个数据帧的最大值向量,然后将该向量分配给每个原始数据帧。 (在 ggplot2 中对齐绘图时需要这样的代码。)
data_list <- lapply(1:3, function(x) data.frame(x=rnorm(10), y=rnorm(10), z=rnorm(10)))
max_x <- do.call(pmax, lapply(data_list, function(d){d$x}))
for( i in 1:length(data_list))
{
data_list[[i]]$x <- max_x
}
有没有办法在没有for 循环的情况下编写最后一部分?
我收到的一些问题的答案:
是什么让我认为会制作副本?我不确定是否会制作副本。我正在处理的实际场景涉及整个 ggplot 图(参见例如here)。由于它们相当大且复杂,因此不得复制。
for循环有什么问题?我宁愿直接遍历一个列表,也不愿引入一个计数器。我不喜欢柜台。为什么不使用
data.table?因为我实际上是在操作 ggplot 图,而不是数据框。此处提供的代码只是一个简化示例。
【问题讨论】:
-
是什么让您认为正在复制整个对象?
-
@MichaelChirico 循环内的第一个赋值似乎是复制:
library(data.table); for( i in 1:length(data_list)) { print(address(data_list)); data_list[[i]]$x <- max_x; print(address(data_list)) } -
@Claus Wilke:使用
for循环有什么问题? -
R 将仅复制包含 data.frame 和修改后的列的列表结构(3 个单元格)。不需要复制未修改的列——它们是共享的。即不会复制
y和z列:library(data.table); for( i in 1:length(data_list)) { print(address(data_list[i]$y)); data_list[[i]]$x <- max_x; print(address(data_list[i]$y)) } -
没有 for 循环:
sapply(1:3,function(y){ data_list[[y]]$x<<-max_x })。如果我使用 Roland 的方法,似乎没有复制完成,但我不是 100% 确定。
标签: r