Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assignment to the result of a function changes variable

Tags:

r

Looking through the ave function, I found a remarkable line:

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

Interestingly, this line changes the value of x, which I found unexpected. I expected that split(x,g) would result in a list, which could be assigned to, but discarded afterward. My question is, why does the value of x change?

Another example may explain better:

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

Not only has a changed, but it changed to a value that does not look like the right hand side of the assignment! Even if assigning to split(a,a$id) somehow changes a (which I don't understand), why does it result in a data.frame instead of a list?

Note that I understand that there are better ways to accomplish this task. My question is why does split(a,a$id)<-lapply(split(a,a$id),function(x) x[which.max(x$value),]) change a?

like image 484
nograpes Avatar asked Oct 10 '12 16:10

nograpes


1 Answers

The help page for split says in its header: "The replacement forms replace values corresponding to such a division." So it really should not be unexpected, although I admit it is not widely used. I do not understand how your example illustrates that the assigned values "do not look like the RHS of the assignment!". The max values are assigned to the 'value' lists within categories defined by the second argument factor.

(I do thank you for the question. I had not realized that split<- was at the core of ave. I guess it is more widely used than I realized, since I think ave is a wonderfully useful function.)

like image 142
IRTFM Avatar answered Nov 13 '22 19:11

IRTFM