6

浏览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(我不明白),为什么它会导致 adata.frame而不是 a list

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

4

3 回答 3

2

split 的帮助页面在其标题中说:“替换形式替换与这种划分相对应的值。” 所以它真的不应该是意外的,虽然我承认它没有被广泛使用。我不明白您的示例如何说明分配的值“看起来不像分配的 RHS!”。最大值分配给第二个参数因子定义的类别中的“值”列表。

(我非常感谢你的问题。我没有意识到这split<-是 . 的核心ave。我想它的使用比我意识到的更广泛,因为我认为这ave是一个非常有用的功能。)

于 2012-10-10T17:00:48.960 回答
1

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

> a
  id value
1  1     1
2  1     1
3  1     1
4  1     1
于 2012-10-10T16:53:41.583 回答
0

这里的关键是 split<- 实际上用 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<-like so的定义

> `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>
于 2012-10-10T16:54:52.283 回答