Należy użyć operatora [[
, a nie [
.
a <- 1
b <- 2
eval(x[[1]][[2]])
## [1] 4
To dlatego, że chcesz, aby wydobyć informacje z obiektu języka, a nie do jej podzbiór (zajrzeć do wnętrza 2-ej, a nie zwraca podciąg składający się z 2-ej).
Innymi słowy, podzbiorów call
daje Ci call
:
x[[1]][2]
## (a + b + 1)()
a ponieważ nie ma takiej funkcji jak a+b+1
(w rzeczywistości wynikiem oceny a+b+1
„s nie jest obiektem funkcji), R zgłasza błąd.
Co ciekawe, jeśli +
zwróci obiekt funkcji, może to mieć sens:
"+" <- function(a, b) { function() print(":-)") }
(a+b+1)()
[1] ":-)"
Z drugiej strony, wyodrębnianie element z obiektu połączenia daje wyrażenia, które mogą być oceniane:
x[[1]][[2]]
a + b + 1
(BTW, to wyrażenie jest również wezwanie, o równowartość "+"(a, "+"(b, 1))
.
EDYTUJ. Bardziej formalnie, wezwanie jest wyrazem (sekwencja) w postaci:
(f, a1, ..., an),
które normalnie odczytać jako:
f(a1, ..., an).
Tak więc pierwszy element ciągu jest obiekt wykorzystywany do przekształcenia inne elementy, aby uzyskać wartość wyjściową.
tutaj x[[1]]
odpowiada:
(sin, a+b+1)
oraz, bardziej szczegółowo,
(sin, (+, a, (+, b, 1))).
Zatem x[[1]][2]
wykonuje podciągiem powyżej składa się z tylko 2-ej i zwrotów:
((+, a, (+, b, 1)))
(tj. (a+b+1)()
- brak argumentów!).Natomiast x[[1]][[2]]
ekstraktów (patrzy wewnątrz) z 2-ej i daje:
(+ a, (+ b, 1)),
tj a+b+1
(nutę nawiasach mniej).
EDIT2: Wszystko to jest uosobieniem piękna i ekspresji języka R, przynajmniej IMHO. Przyjrzyjmy się kolejny przykład, w którym tworzymy połączenia f1(f2(f3, f4), f3, f4)
, które mogą być reprezentowane przez sekwencję
(f1, (f2, f3, f4), f3, f4).
Mamy:
f <- function(...) invisible(NULL)
f1 <- f; f2 <- f; f3 <- f; f4 <- f # for sake of clarity below
expr <- quote(f1(f2(f3, f4), f3, f4))
print(expr)
## f1(f2(f3, f4), f3, f4), i.e. (f1, (f2, f3, f4), f3, f4)
print(expr[1:3])
## f1(f2(f3, f4), f3), i.e. (f1, (f2, f3, f4), f3)
print(expr[3:4])
## f3(f4), i.e. (f3, f4)
print(expr[3])
## f3(), i.e. (f3)
expr[2]
## f2(f3, f4)(), i.e. ((f2, f3, f4)) [subsetting!]
A teraz coś z zupełnie innej beczki:
expr[[2]]
## f2(f3, f4), i.e. (f2, f3, f4) [extraction]
Mam nadzieję, że to trochę wyjaśnia te problemy.
Obie klasy (x [[1]] [[2]]) i klasa (x [[1]] [2]) to połączenia. – qed
Jeden daje ci wezwanie do '(a + b + 1)()' a drugi do '" + "(a," + "(b, 1))'. – gagolews
Wprowadziłem kilka zmian, mam nadzieję, że wyjaśnią więcej tego skomplikowanego tematu. :) – gagolews