对函数结果的赋值更改变量

时间:2012-10-10 16:38:58

标签: r

通过ave功能,我发现了一条非凡的路线:

split(x, g) <- lapply(split(x, g), FUN) # From ave

有趣的是,这一行改变了x的值,我发现这是意料之外的。我希望split(x,g)会产生一个列表,该列表可以分配给,但之后会被丢弃。我的问题是,为什么x的价值会发生变化?

另一个例子可以更好地解释:

a <- data.frame(id=c(1,1,2,2), value=c(4,5,7,6))
#   id value
# 1  1     4
# 2  1     5
# 3  2     7
# 4  2     6

split(a,a$id) # Split a row-wise by id into a list of size 2
# $`1`
#   id value
# 1  1     4
# 2  1     5
# $`2`
#   id value
# 3  2     7
# 4  2     6

# Find the row with highest value for each id
lapply(split(a,a$id),function(x) x[which.max(x$value),])
# $`1`
#   id value
# 2  1     5
# $`2`
#   id value
# 3  2     7

# Assigning to the split changes the data.frame a!
split(a,a$id)<-lapply(split(a,a$id),function(x) x[which.max(x$value),])
a
#   id value
# 1  1     5
# 2  1     5
# 3  2     7
# 4  2     7

不仅a发生了变化,而且变成了一个看起来不像作业右侧的值!即使分配给split(a,a$id)以某种方式更改a(我不明白),为什么会导致data.frame而不是list

请注意,我了解有更好的方法可以完成此任务。我的问题是为什么split(a,a$id)<-lapply(split(a,a$id),function(x) x[which.max(x$value),])会更改a

3 个答案:

答案 0 :(得分:2)

split的帮助页面在其标题中显示:“替换表单替换对应于此类划分的值。”所以它确实不应该出乎意料,尽管我承认它并没有被广泛使用。我不明白你的例子如何说明指定的值“看起来不像赋值的RHS!”。最大值分配给第二个参数因子定义的类别中的“值”列表。

(我确实感谢你提出这个问题。我没有意识到split<-ave的核心。我猜它比我意识到的更广泛,因为我认为{{1这是一个非常有用的功能。)

答案 1 :(得分:1)

在定义a之后,执行split(a, a$id)=1,结果将是:

> a
  id value
1  1     1
2  1     1
3  1     1
4  1     1

答案 2 :(得分:0)

这里的关键是split&lt; - 实际上用RHS值修改了LHS。

以下是一个例子:

> x <- c(1,2,3);
> split(x,x==2)
$`FALSE`
[1] 1 3
$`TRUE`
[1] 2
> split(x,x==2) <- split(c(10,20,30),c(10,20,30)==20)
> x
[1] 10 20 30

请注意我重新分配split(x,x==2) <-的行。这实际上重新分配了x

如下面的评论所述,您可以像{<}}一样查找split<-的定义

> `split<-.default`
function (x, f, drop = FALSE, ..., value) 
{
    ix <- split(seq_along(x), f, drop = drop, ...)
    n <- length(value)
    j <- 0
    for (i in ix) {
        j <- j%%n + 1
        x[i] <- value[[j]]
    }
    x
}
<bytecode: 0x1e18ef8>
<environment: namespace:base>