通过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
?
答案 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>