2012-10-10 10 views
6

Patrząc przez funkcję ave znalazłem niezwykłą linię:Przypisanie do wyniku funkcji zmienia zmienną

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

Co ciekawe, ta linia zmienia wartość x, który znalazłam nieoczekiwane. Spodziewałem się, że split(x,g) spowoduje wyświetlenie listy, do której można przypisać, ale później ją odrzucić. Moje pytanie brzmi, dlaczego zmienia się wartość x?

Innym przykładem może lepiej wyjaśnić:

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 

Nie tylko a zmieniło, ale zmieniona na wartość, która nie wygląda na prawej stronie przypisania! Nawet jeśli przypisanie do split(a,a$id) w jakiś sposób zmienia a (czego nie rozumiem), dlaczego powoduje to data.frame zamiast list?

Należy pamiętać, że rozumiem, że istnieją lepsze sposoby wykonania tego zadania. Moje pytanie brzmi: dlaczego split(a,a$id)<-lapply(split(a,a$id),function(x) x[which.max(x$value),]) zmienia a?

+2

Funkcja, którą wywołujesz, to 'split <-', a nie' split'. Są to dwie różne funkcje. Spójrz na 'split <-. Default' i jest oczywiste, dlaczego' a' się zmienia. –

+0

Musisz użyć cudzysłowów, aby wydrukować tę funkcję, ponieważ nazwa funkcji zawiera operator: '\' split <-. Default \ ''. –

+0

Czy w tym przypadku odpowiednia funkcja nie byłaby '\' split <-. Data.frame \ ''? – nograpes

Odpowiedz

2

Strona pomoc dla rozłamu mówi w jego nagłówku: „Formy zamienne zastąpić wartości odpowiadające takiego podziału. " Tak naprawdę nie powinno być niespodziewanie, chociaż przyznaję, że nie jest powszechnie stosowany. Nie rozumiem, jak twój przykład pokazuje, że przypisane wartości "nie wyglądają jak RHS zadania!". Maksymalne wartości są przypisywane do list "wartości" w kategoriach zdefiniowanych przez drugi argument.

(ja dziękuję za to pytanie. Nie zdawałam sobie sprawy, że split<- był na rdzeniu ave. Myślę, że jest coraz szerzej stosowane niż zdałem sobie sprawę, ponieważ myślę ave jest wspaniale przydatna funkcja.)

+0

Rozumiem. Mój problem polegał na tym, że nie zdawałem sobie sprawy, że 'split <-' jest funkcją. Podejrzewam, że tej funkcji można użyć w przypadku bardzo sprytnego, zwięzłego i wydajnego kodu. Dzięki za odpowiedź. – nograpes

+0

Typ: metody (\ "split <- \') –

1

Tuż po definicji a wykonać split(a, a$id)=1, wynik będzie:

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

'split' nie zwraca wyników przez odniesienie. –

+0

@DWin Dziękuję Poprawiłem moją odpowiedź – Ali

0

Kluczem tutaj jest to, że rozłam < - rzeczywiście zmodyfikował LHS z wartościami RHS.

Oto przykład:

> 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 

Uwaga linia gdzie ponownie przypisać split(x,x==2) <-. To faktycznie zmienia przypisanie x.

W komentarzach poniżej stwierdziły, można spojrzeć na definicję split<- jak tak

> `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> 
+2

'split <-' jest tym co nazywa się i jest napisane w R. –

+0

Jak wyświetliłbyś kod dla tego.Przynajmniej do dzielenia, mogę po prostu wpisać "split" i wyprowadza: funkcja (x, f, drop = FALSE, ...) UseMethod ("split") Arcymag

+0

I dodać do tego, co Joshua mówi, że podzielił (na RHS) _ zwraca_ wartości i NIE przechodzi przez referencję. –

Powiązane problemy