2014-06-26 10 views
5

Ostatnio grałem z tworzeniem własnych rur, używając niesamowitej funkcji pipe_with() w magittr. Szukam śledzić liczbę rur w bieżącym łańcuchu (więc moja rura może zachowywać się inaczej w zależności od jego pozycji w łańcuchu). Myślałem, że odpowiedź z tego przykładu ze strony magrittr github:Skąd wiadomo, czy operator rury jest ostatnim (lub pierwszym) łańcuchem?

# Create your own pipe with side-effects. In this example 
# we create a pipe with a "logging" function that traces 
# the left-hand sides of a chain. First, the logger: 
lhs_trace <- local({ 
    count <- 0 
    function(x) { 
    count <<- count + 1 
    cl <- match.call() 
    cat(sprintf("%d: lhs = %s\n", count, deparse(cl[[2]]))) 
    } 
}) 

# Then attach it to a new pipe 
`%L>%` <- pipe_with(lhs_trace) 

# Try it out. 
1:10 %L>% sin %L>% cos %L>% abs 

1: lhs = 1:10 
2: lhs = 1:10 %L>% sin 
3: lhs = 1:10 %L>% sin %L>% cos 
[1] 0.6663667 0.6143003 0.9900591 0.7270351 0.5744009 0.9612168 0.7918362 0.5492263 0.9162743 0.8556344 

Liczba po lewej stronie jest numer rury. Jednak, kiedy ponownie uruchomić ten sam łańcuch, numery nie uruchamiaj ponownie na 1:

> 1:10 %L>% sin %L>% cos %L>% abs 
4: lhs = 1:10 
5: lhs = 1:10 %L>% sin 
6: lhs = 1:10 %L>% sin %L>% cos 
[1] 0.6663667 0.6143003 0.9900591 0.7270351 0.5744009 0.9612168 0.7918362 0.5492263 0.9162743 0.8556344 

Jest to prawdopodobnie dlatego, że lokalne środowisko stworzone przez pierwszego użycia %L>% nie ulega zniszczeniu, gdy ostatni %L>% w łańcuchu jest wykonywany. Aby więc określić położenie rury w bieżącym łańcuchu (a nie tylko od pierwszej rury w sesji), musi istnieć sposób na ustawienie zmiennej liczenia z powrotem na 0, gdy łańcuch się skończy (lub zresetowanie lokalne środowisko).

Czy ktoś ma jakieś pomysły, jak to zrobić?

Odpowiedz

4

W obecnej dev gałęzi, pracujemy z nowym podejściem , ze względu na operatora złożonego, %<>%, gdzie ostatnia rura musi wiedzieć, że jest ostatni. W każdym razie sugeruje się, że rura stosunkowo szybko ma wiedzę na ten temat poprzez lokalną wartość toplevel, która ma wartość TRUE lub FALSE. Nie wiem, czy to ma jakiekolwiek znaczenie.

W szczególności dlatego, że pipe_with jest "wstrzymany" ze względu na bardzo ograniczone odsetki otrzymane w nim. Dlatego nie jest częścią bieżącego oddziału dev.

+0

Dobrze wiedzieć! Chyba lepiej zapoznaję się z gałęzią 'dev' i zobaczę, co mogę z tym zrobić. Dzięki! – ecologician

+0

tak, kiedy mam czas, dev będzie prawdopodobnie mistrzem, a wiele innych zostanie usuniętych. – Stefan

+1

Zobacz tę treść dla innej sugestii https://gist.github.com/smbache/86fe703fa46e39df33ea – Stefan

2

Właściwie, wystarczy pomyśleć o jednym sposobie, aby to zrobić. Wystarczy policzyć liczbę wystąpień podciągu „% L>” w match.call:

> lhs_trace2 <- function(x) { 
+  cl <- match.call() 
+  counter <- gregexpr("%L>%", cl[[2]], fixed = TRUE)[[1]] 
+  if (counter[1] == -1) count <- 1 else count <- length(counter) + 1 
+  cat(sprintf("%d: lhs = %s\n", count, deparse(cl[[2]]))) 
+ } 
> 
> # Then attach it to a new pipe 
> `%L>%` <- pipe_with(lhs_trace2) 
> 
> # Try it out. 
> 1:10 %L>% sin %L>% cos %L>% abs 
1: lhs = 1:10 
2: lhs = 1:10 %L>% sin 
3: lhs = 1:10 %L>% sin %L>% cos 
[1] 0.6663667 0.6143003 0.9900591 0.7270351 0.5744009 0.9612168 0.7918362 0.5492263 0.9162743 0.8556344 

następnie uruchomić go ponownie:

> 1:10 %L>% sin %L>% cos %L>% abs 
1: lhs = 1:10 
2: lhs = 1:10 %L>% sin 
3: lhs = 1:10 %L>% sin %L>% cos 
[1] 0.6663667 0.6143003 0.9900591 0.7270351 0.5744009 0.9612168 0.7918362 0.5492263 0.9162743 0.8556344 
Powiązane problemy