Assigning the result of a variable to a function change

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

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

Interestingly, this line changes the value of x , which turned out to be unexpected. I was expecting split(x,g) result in a list that could be assigned, but then dropped later. My question is: why does the value of x change?

Another example might 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 a was changed, but it changed to a value that does not look like the right side of the job! Even if assigning split(a,a$id) somehow changes a (which I don't understand), why does this lead to data.frame instead of list ?

Please 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 ?

+6
source share
3 answers

The help page for split says in its headline: "Replaceable forms replace values ​​corresponding to such a division." So this really should not be unexpected, although I admit that it is not widely used. I don’t understand how your example illustrates that the assigned values ​​are “not like RHS assignments!”. Maximum values ​​are assigned to value lists in the categories specified by the second argument.

(I thank you for this question. I did not understand that split<- is the basis of ave . I assume that it is more widely used than I understood, since I think that ave is a wonderfully useful function.)

+2
source

Immediately after defining a execute split(a, a$id)=1 , the result will be:

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

The key here is that split <- has actually modified LHS with RHS values.

Here is an example:

 > 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 

Notice the line where I rewrite split(x,x==2) <- . This really reassigns x .

As indicated below, you can find the definition of split<- so that

 > `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> 
0
source

Source: https://habr.com/ru/post/927375/


All Articles